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

C# 在C中创建不透明指针(引用)#,c#,opaque-pointers,C#,Opaque Pointers,我有一个类(基本上是一个链表,所以我们称之为list),它使用另一个类来存储数据(节点,所以我们称该类为Node)节点具有必须从列表调用的方法,但是从其他地方调用它们可能会很麻烦。我需要程序的其他部分使用节点的引用,但只能通过列表 在C++中,我将创建另一个类(我们称之为代码节点< /COD>”,并公开了一些“代码>节点< /COD>的成员,如果这被传递到列表,指向实际节点< /C>的指针将被“解压缩”并在内部使用,但是在C#中,我没有想到一种方法,可以在程序的其余部分隐藏对节点的引用,而不使列

我有一个类(基本上是一个链表,所以我们称之为
list
),它使用另一个类来存储数据(节点,所以我们称该类为
Node
)<代码>节点具有必须从
列表
调用的方法,但是从其他地方调用它们可能会很麻烦。我需要程序的其他部分使用
节点的引用
,但只能通过
列表

在C++中,我将创建另一个类(我们称之为代码<不透明),它有一个私有指针指向“代码>节点< /COD>”,并公开了一些“代码>节点< /COD>的成员,如果这被传递到列表,指向实际<代码>节点< /C>的指针将被“解压缩”并在内部使用,但是在C#中,我没有想到一种方法,可以在程序的其余部分隐藏对
节点的引用,而不使
列表
无法访问
有没有办法做到这一点,或者有没有一些C语言特有的习惯用法具有相同的功能

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

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

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

接下来是程序集的级别,它是使用
internal
关键字指定的。假设list类和node类共享同一个程序集,这就是您应该能够使用的:

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

明显的缺点是node类的内部方法对库中的所有类都可见,而不仅仅是对列表可见。然而,有人会认为C++中的不透明引用的内部结构对于访问内部标头的每个人都是可见的,因此在两种语言之间得到了密切匹配的功能。

< P>我可以建议您使用接口来为节点值(或至少派生类)使用,并通过应用程序传递它。但您将尝试将其强制转换为使用高级功能:

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)
            // ...
    }
}
当然,这不是真正的隐藏(任何知道
节点的人都可以使用它),但对于大多数使用场景来说,它就足够了。

那怎么办

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
{
字符串名称{get;}
}
公共班级名单
{
私有类节点:INode
{
公共字符串名称{get;set;}
公共节点下一个{get;set;}
}
私有列表_items=新列表();
公共索引节点GetItemAt(int索引)
{
返回项目[索引];
}
公共索引节点GetNextItem(索引节点项)
{
返回(项目为节点)?((节点)项目)。下一步:空;
}
}
如果只有
INode
是公开可见的,那么实现细节将被隐藏

如果有很多内部代码与
节点一起工作
,那么最好按照@eugene podskal的建议将类标记为
内部
,因为
节点
类将可供居住在同一原始程序集中的许多“朋友”访问(有关此辅助功能模型的详细说明,请参阅)


内部
概念本身并没有错(正如@dasblinkenlight提出并随后提出争议的那样)它也经常被.NET框架使用,参见示例或各种.NETFramework内部类。可以使用例如在代码< >代码>微软> Win32。Win32。Suffice处理< /COD> < /P>在C.*单独的类Prima中尝试C++解决方案时会看到整个内部.NETFramework命名空间的示例。TI引用,委托成员?我尝试过,但是如果我把节点私有化嵌套在列表中,然后创建另一个类,它通过一个私有引用来引用节点,我不能从内部列表中获取引用。在C++中,可以通过使类<代码>朋友< /> >或者将实际实现粘贴到.CPP中来解决。文件,但c#没有
friend
,而且AFAIK没有头(.h)/实现代码(.cpp)也可以是结构。我正在与其他人一起处理这个项目,因此我希望避免错误地调用Node方法而不是List方法,这会导致错误,可能很难找到。也许如果可以将该类拆分为一个单独的程序集?哦,顺便说一下,使用C#,可以直接访问NodE方法默认情况下,在C++中,他们必须“代码> >包含内部< /Cord>关键字,这使得它在给定程序集中的所有代码都可见。我想使它只对一个类可见。但是如果没有办法,我可能会接受达斯布林克林的ANS。wer,因为它正确地解释了这个小问题。@Tomeamis您可以将
节点
作为私有类移动到
MyList
中。这个答案的要点是您应该发布并使用
INode
外部作为不透明类型,我认为程序其余部分中使用的所有变量都声明为
INode
关于嵌套的私有类,但似乎
节点
是在MyList类之外创建的,否则工厂模式就是一个答案。在任何情况下,由OP来澄清和决定。节点是在
列表
内创建的。如果我理解正确,那么
名称
属性实际上并不是用来做任何事情的,而是一个因此,传递对
INode
的引用实际上不允许其用户对
节点执行任何操作,而不将其传递给
列表
,这正是我所需要的。@Tomeamis是的,
Name
属性是一个只能通过
INode
接口读取的示例(无害).为了分配