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

本文关键字:引用 指针 不透明 创建 | 更新日期: 2023-09-27 18:23:47

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

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

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

怎么样

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.SafeHandlessystem.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的人都可以使用它(,但对于大多数使用场景来说,它就足够了。