C# 限制对需要从其他部件指定的特性的访问的正确方法是什么?

C# 限制对需要从其他部件指定的特性的访问的正确方法是什么?,c#,.net,C#,.net,例如,我在程序集A中定义了以下代码: public abstract class Message { public int ID { get; internal set; } public Message Parent { get; internal set; } } 在程序集B中,我需要执行以下操作: instanceOfMessage.ID = MethodToGetUniqueIDNumber(); instanceOfMessage.Parent = MethodToG

例如,我在程序集A中定义了以下代码:

public abstract class Message
{
    public int ID { get; internal set; }
    public Message Parent { get; internal set; }
}
在程序集B中,我需要执行以下操作:

instanceOfMessage.ID = MethodToGetUniqueIDNumber();
instanceOfMessage.Parent = MethodToGetParent(); // Returns null /w no parent
目前,我正在使用编译器选项来解决这个问题:

[assembly:InternalsVisibleTo ("AssemblyB")]

// Namespace stuff here

public class Message
{
    public int ID { get; internal set; }
}
要让这项工作正常运行,就必须搞乱编译器选项,这感觉有点怪怪的。因此,我的问题是:

  • 在这种情况下使用InternalsVisibleTo可以吗
  • 我是不是应该把这些财产公之于众,希望没有人改变什么
  • 我应该这样做吗
我的最终目标是,有人,可能只是我的团队和我,应该能够使用一条消息,但必须确保像ID这样的属性永远不会从管理它们的类之外更改。然而,我们仍然需要创建消息的实例等等

我的最终目标是,我的团队和我应该能够从第三个程序集中的消息继承,即程序集C。程序集C只知道程序集a。程序集B稍后将动态加载。C将使用A提供的接口向B发送消息

我的最终目标是,有人,可能只是我的团队和我,应该能够使用一条消息,但必须确保像ID这样的属性永远不会从管理它们的类之外更改。然而,我们仍然需要创建消息的实例等等

这种情况下的一种常见方法是实际使用消息接口,然后在AssemblyB中实现接口

这允许您创建消息,但不能在以后修改,因为您仍然可以完全控制实现

public interface IMessage
{
    int ID { get; }
    IMessage Parent { get;  }
}

然后,您的另一个程序集就可以使用私有类实现这一点,并返回适当的消息,而不必担心它会被修改。

为什么不在调用构造函数时使用
private set
并定义
ID
Parent

public class Message
{
    public Message(int id, Message parent) // Message constructor taking in ID and parent from external
    {
        ID = id;
        Parent = parent;
    }

    public int ID { get; private set; }
    public Message Parent { get; private set; }
}
下面的调用来自您的
消息
类之外

Message instanceOfMessage = new Message(MethodToGetUniqueIDNumber(), MethodToGetParent());

我可能会更进一步,创建一个静态工厂方法:

public class Message
{
    public static Message CreateInstance(int id, Message parent)
    {
        // Add code here to check security of caller

        return new Message(id, parent);
    }

    private Message(int id, Message parent)  
    {
        ID = id;
        Parent = parent;
    }

    public int ID { get; private set; }
    public Message Parent { get; private set; }
}
要创建您现在要调用的消息的实例,请执行以下操作:

Message instanceOfMessage = Message.CreateInstance(MethodToGetUniqueIDNumber(), MethodToGetParent());    

现在,我可以完全控制对象实例的创建,一旦创建,它就不能被修改。

您已经考虑过
internal
public
。还有一种可能性是
protected
,这意味着只能在从
Message
派生的类(甚至是其他程序集中的类)中设置属性。这回答了问题,但是我在最终目标中犯了一个错误,忘了定义“use”一词的含义。应该是“继承自”。请查看上面的编辑。@MGSoto他们需要对其进行子类化,还是只提供消息“详细信息”?如果是,则可以是方法类型的成员,而不是实际的“消息'子类…?是的,消息必须子类化,因为消息的详细信息将通过添加其他属性而更改。@MGSoto在您的情况下,使用带有消息详细信息的
IMessage
作为
T
可能更合适。在这种情况下,你可以创建一条包含任何内容的消息……很好,应该可以适当地处理我的情况。非常感谢。你好,谢谢你的回答。我做了一些编辑来澄清这个问题,因为我错过了一篇重要的文章。这些属性需要在类的实例已经创建之后设置。