I have a class (basically a linked list, so let's call it List
) that uses another class to store data (the nodes, so let's call the class Node
). Node
has methods that must be called from List
, but calling them from elsewhere could be messy. I need other parts of my program to use references of Node
, but to change them only through List
.
In C++ I would create another class (let's call it Opaque
) that has a private pointer to Node
and expose some members of Node
, and if this was passed to List
, the pointer to the actual Node
would be "unpacked" and used internally, but in C# I have not thought of a way to hide the reference to the Node
from the rest of the program without also makking it inaccessible to List
.
Is there any way to do it or some C#-specific idiom that has the same functionality?
CLARIFICATION: I would like to make it visible to the List
class only. I already know about the internal
keyword.
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;
}
}
Where only the INode
would be publicly visible, implementation details hidden.
In case there would be lots of the internal code working with the Node
then it is better to mark the class as internal
as suggested by @eugene-podskal as then the Node
class will be accessible to many "friends" living in the same original assembly (see MSDN: internal (C# reference) for more detailed description of this accessibility model)
There is nothing wrong per-se with the internal
concept (as proposed and then disputed by @dasblinkenlight). It is also quite often used by the .NET framework, see http://referencesource.microsoft.com/#q=internal for examples or various .NET framework internal classes. An example of whole internal .NET framework namespaces can be seen using ILSpy e.g. at system.dll
in namespace Microsoft.Win32.SafeHandles
In C# has two levels of granularity for information hiding.
The most basic one is the class itself: this is the scope that you get when you declare a member private
. This is not sufficient for your purposes, because the node and the list are different classes.
Next up is the level of the assembly, which is designated using the internal
keyword. This is what you should be able to use for your purposes, assuming that the list class and the node class share 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 inside your library, not only to the list. However, one could argue that internals of an opaque reference in C++ are visible to everyone who has access to the internal headers, so you get a closely matched functionality between the two languages.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With