我有一个类(基本上是一个链表,所以我们称之为List
(,它使用另一个类来存储数据(节点,所以让我们称类为Node
(。 Node
有必须从List
调用的方法,但是从其他地方调用它们可能会很混乱。我需要程序的其他部分使用Node
的引用,但只能通过List
来更改它们。
在C++中,我将创建另一个类(我们称之为Opaque
(,该类具有指向Node
的私有指针并公开Node
的一些成员,如果将其传递给List
,则指向实际Node
的指针将被"解压缩"并在内部使用,但是在C#中,我没有想到一种方法可以从程序的其余部分隐藏对Node
的引用,而不会同时标记List
无法进入.
有没有办法做到这一点或一些具有相同功能的特定于 C# 的习语?
澄清:我想让它只对List
类可见。我已经知道internal
关键字。
怎么样
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;
}
}
如果只有INode
是公开可见的,则隐藏了实现细节。
如果有很多内部代码使用Node
那么最好按照 @eugene-podskal 的建议将该类标记为internal
,这样Node
类将被居住在同一原始程序集中的许多"朋友">访问(有关此辅助功能模型的更详细说明,请参阅 MSDN:内部(C# 参考((
internal
概念本身没有错(正如@dasblinkenlight提出并提出异议(。它也经常被.NET框架使用,请参阅 http://referencesource.microsoft.com/#q=internal 示例或各种.NET框架内部类。可以使用 ILSpy 看到整个内部 .NET 框架命名空间的示例,例如在命名空间Microsoft.Win32.SafeHandles
的 system.dll
在 C# 中,信息隐藏有两个粒度级别。
最基本的是类本身:这是您在声明成员private
时获得的作用域。这对于您的目的来说是不够的,因为节点和列表是不同的类。
接下来是程序集的级别,它是使用 internal
关键字指定的。这是您应该能够用于您的目的的内容,假设列表类和节点类共享相同的程序集:
public class Node {
internal void SpecialMethod() {
...
}
}
明显的缺点是节点类的内部方法对库中的所有类都是可见的,而不仅仅是对列表可见。但是,有人可能会争辩说,C++中不透明引用的内部对有权访问内部标头的每个人都可见,因此您可以在两种语言之间获得紧密匹配的功能。
我可以建议你对节点值(或最小派生类(使用接口并通过应用程序传递它,但你List
会尝试投射它以使用高级功能:
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)
// ...
}
}
当然,这不是真正的隐藏(任何了解Node
的人都可以使用它(,但对于大多数使用场景来说,它就足够了。