Creating an opaque pointer (link) in C #

I have a class (basically a linked list, so call it List

) that uses another class to store data (nodes, so call the class Node

). Node

has methods to be called from List

, but calling them from elsewhere can be messy. I need other parts of my program to use links Node

, but only change them through List

.
In C ++ I would create another class (let's call it Opaque

) that has a private pointer to Node

and exposes some members Node

, and if that was passed to List

, the pointer to the actual Node

would be "unpacked" and used internally, but in C # I did not think about how to hide the link toNode

from the rest of the program without making it inaccessible to List

.
Is there a way to do this, or some C #-specific idiom with the same functionality?

CONFIRMATION: I would like to make it visible to the class only List

. I already know about the keyword internal

.

+3


source to share


3 answers


What about

public interface INode
{
    string Name { get; }
}

public class List
{
    private class Node : INode
    {
        public string Name { get; set; }
        public Node Next { get; set; }
    }

    private List<Node> _items = new List<Node>();

    public INode GetItemAt(int index)
    {
        return _items[index];
    }

    public INode GetNextItem(INode item)
    {
        return (item is Node) ? ((Node)item).Next : null;
    }
}

      



If only INode

publicly available, implementation details are hidden.

In case there is a lot of internal code working with Node

, then it is better to mark the class as internal

as suggested by @ eugene-podskal, then the class Node

will be accessible to many "friends" living in the same original assembly (see MSDN: internal (link to C #) for a more detailed description of this accessibility model)

There is nothing wrong with the concept internal

(as suggested and then disputed by @dasblinkenlight). It is also used quite frequently by the .NET framework, see http://referencesource.microsoft.com/#q=internal for examples or various internal .NET framework classes. An example of entire .NET .NET internal namespaces can be seen using ILSpy for example. in system.dll

in namespaceMicrosoft.Win32.SafeHandles

+3


source


There are two levels of verbosity in C # for hiding information.

The simplest of these is the class itself: this is the scope that you get when you declare a member private

. This is not enough for your purposes, because node and list are different classes.

The next step is the build level, which is assigned using a keyword internal

. This is what you should use for your own purposes, assuming that the list class and the node class are using the same assembly:



public class Node {
    internal void SpecialMethod() {
        ...
    }
}

      

The obvious downside is that the internal methods of the node class are visible to all classes within your library, not just this list. However, one could argue that the internals of an opaque C ++ reference are visible to anyone with access to the inner headers, so you get tightly coupled functionality between the two languages.

+2


source


I can suggest that you use an interface for your node (or least derived class) values ​​and pass it through your application, but you List

will try to use it for additional functionality:

public interface INode
{
    void DoPublic();
}

// As it is pointed by @xmomjr
internal class Node : INode
{
    public void DoPublic(){}
    public void DoHidden(){}
}

public class MyList
{
    public void Process(INode node)
    {
        if (node is Node)
            // ...
    }
}

      

Of course it isn't what to hide (anyone in the know Node

can use it), but for most use cases, this will be enough.

+2


source







All Articles