Search code examples
c#.netoopaccess-modifiers

Why is the internal keyword used in this example from Jon Skeet's book?


I've been trying to understand the internal keyword and when I need to use it. Fortunately, today, as I'm reading in Jon Skeet's book C# In Depth, 3rd Edition about how to implement iterators, on p.161-162 there is a use for internal:

Listing 6.32

using System;
using System.Collections;

public class IterationSample : IEnumerable
{
    object[] values;
    int startingPoint;

    public IterationSample(object[] values, int startingPoint)
    {
        this.values = values;
        this.startingPoint = startingPoint;
    }

    public IEnumerator GetEnumerator()
    {
        throw NotImplementedException();
    }
}

Listing 6.3

class IterationSampleIterator : IEnumerator
{
    IterationSample parent;
    int position;

    internal IterationSampleIterator(IterationSample parent)
    {
        this.parent = parent;
        position = -1;
    }

    public bool MoveNxt()
    {
        if (position != parent.values.Length)
        {
            position++'
        }
        return position < parent.values.Length;
    }

    public object Current
    {
        get 
        {
            if (position == -1 ||
                position == parent.values.Length)
            {
                throw new InvalidOperationException();
            }
            int index = position + parent.startingPoint;
            index = index % parent.values.Length;
            return parent.values[index];
        }
    }

    public void Reset()
    {
        position = -1;
    }
}

So why internal IterationSampleIterator? As I understand, internal is usually in place of public; so help me understand why public IterationSampleIterator could cause problems that are solved by replacing public with internal.


Solution

  • Before going any deeper in the posted code, you may review the MSDN Link on access modifiers in .Net C#.

    Idea remains we make something internal when we want that to be accessed only within the assembly (mostly dll). It may seem similar to public, but usage is quite different, since for public its an open access for all the callers from anywhere.

    In the code sample the usage of internal has a different perspective, this is more to control the object of the IterationSampleIterator class, by making the constructor internal, so this class can only be instantiated from the callers within its own assembly, but any other caller from outside cannot do it.

    For all the users outside the assembly they can only call the methods like property like Current or Methods like MoveNext and Reset to work with internal implementation there's no direct access to the object.

    Normally such would be the case where within assembly there are certain classes which internally use and thus expose the wrapped functionality. I think System.IO is one of the assemblies exposing such classes, with can be used within the assembly boundaries