在C#中创建不透明指针(引用)

时间:2014-09-20 16:04:08

标签: c# opaque-pointers

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

澄清:我想让它仅在List课程中可见。我已经了解internal关键字。

3 个答案:

答案 0 :(得分: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一起使用,那么最好按@ eugene-podskal建议的那样将类标记为internal,然后Node许多&#34;朋友&#34; 可以访问同一个原始程序集中的类(有关此辅助功能模型的详细说明,请参阅MSDN: internal (C# reference)

internal概念本身没有任何错误(如提议,然后由@dasblinkenlight提出异议)。它也经常被.NET框架使用,请参阅http://referencesource.microsoft.com/#q=internal示例或各种.NET框架内部类。可以使用ILSpy看到整个内部.NET框架命名空间的示例,例如位于system.dll

Microsoft.Win32.SafeHandles

答案 1 :(得分:2)

在C#中有两个级别的信息隐藏级别。

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

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

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

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

答案 2 :(得分: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的人都可以使用它),但对于大多数使用场景来说,它就足够了。