4

我有一个类(基本上是一个链表,所以我们称之为List),它使用另一个类来存储数据(节点,所以我们称之为类Node)。Node具有必须从 调用的方法List,但从其他地方调用它们可能会很麻烦。我需要程序的其他部分来使用 的引用Node,但只能通过List.
在 C++ 中,我将创建另一个类(我们称之为Opaque),它有一个私有指针Node并公开 的一些成员Node,如果将其传递给List,则指向实际的指针Node将被“解包”并在内部使用,但在 C# 中我有没有想到一种方法来隐藏对Node程序其余部分的引用,同时又使其无法访问List
有什么方法可以做到这一点,或者一些具有相同功能的特定于 C# 的习语吗?

澄清:我想让它只对List全班可见。我已经知道internal关键字。

4

3 回答 3

3

关于什么

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那么最好按照internal@eugene-podskal 的建议标记该类,因为生活在同一个原始程序集中的许多“朋友”Node可以访问该类(参见MSDN : 内部(C# 参考)更详细地描述了这个可访问性模型)

这个概念本身并没有错internal(正如@dasblinkenlight 提出的然后有争议的那样)。.NET 框架也经常使用它,有关示例或各种 .NET 框架内部类,请参见http://referencesource.microsoft.com/#q=internal使用ILSpy可以看到整个内部 .NET 框架命名空间的示例,例如system.dll在命名空间中Microsoft.Win32.SafeHandles

于 2014-09-20T16:42:10.517 回答
2

我可以建议您为节点值(或最小派生类)使用接口并将其传递给应用程序,但您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可以使用它),但对于大多数使用场景来说就足够了。

于 2014-09-20T16:36:56.127 回答
2

在 C# 中,信息隐藏有两个粒度级别。

最基本的是类本身:这是您在声明成员时获得的范围private。这不足以满足您的目的,因为节点和列表是不同的类。

接下来是程序集的级别,使用internal关键字指定。假设列表类和节点类共享相同的程序集,这就是您应该能够用于您的目的:

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

明显的缺点是节点类的内部方法对库中的所有类都是可见的,而不仅仅是列表。但是,有人可能会争辩说,C++ 中不透明引用的内部对所有有权访问内部标头的人都是可见的,因此您可以在两种语言之间获得紧密匹配的功能。

于 2014-09-20T16:11:47.623 回答