有没有一种方法可以使类中的某个对象不可由某些代码重新赋值

本文关键字:代码 赋值 新赋值 对象 方法 一种 可以使 有没有 | 更新日期: 2023-09-27 17:59:06

我有一个Windows服务,它会查看dll列表(在设置文件中),将它们全部加载到中,并在每个dll中的自己线程上启动一个特定的方法。这些dll中的每一个都必须继承自一个特定的类(Module类)才能被此服务使用,而该类的一部分是MPI对象,基本上是一个类的实例,它允许dll方法调用方法与服务直接交互。进展如何:

  1. 服务加载dll
  2. 使用反射检查是否存在继承Module类的类
  3. 创建该模块继承类的新实例
  4. 创建MPI类的新实例。这包含有关哪个模块正在使用它的识别信息
  5. 将新创建的MPI对象分配给新的Module类
  6. 启动主模块线程

基本模块类本身是它自己的dll(这样服务和外部dll都可以使用它)。我想做的是让服务能够将一个MPI对象(具有特殊值)分配给新的Module类,但我不希望该类能够更改MPI对象赋值或其中的任何值。对于继承的类为ReadOnly,但可从其他类赋值。我想我不能按照我设置的方式来做这件事,我必须做什么改变才能做到这一点。这可能吗?

MPI在很大程度上类似于主托管服务的API。它处理一些集中的事情,比如错误日志记录。当服务加载一个新模块时,它会为其分配一个ID。当该模块调用MPI.ErrorLog(someStuff)时,MPI(它引用了主服务内存,因此可以访问实际的错误写入程序)将写入模块ID#此时出现此错误。我希望ID对继承Module的类是私有的,但对主服务不是私有的,这样ID就可以由它来设置。不要说私有变量带有一个设置所有内容的构造函数,因为我不希望Module能够自己创建一个新的MPI对象,并能够改变这些东西。

有没有一种方法可以使类中的某个对象不可由某些代码重新赋值

据我所知,您希望修改不同上下文/用户对单个对象的访问权限。例如,"base"知道get和set访问器,而"module"只知道get访问器。我可以想象这里有两个选项——访问修饰符和接口。

首先,internal修饰符使成员仅对同一程序集中的文件可见。

public class Mpi
{
    private int id;
    int Id
    {
        public get
        {
            return this.id;
        }
        internal set
        {
            this.id = value;
        }
    }
    //...
}

因此,您的"module"将假定这是一个只获取的属性,而您的"base"将能够同时获取和设置。

您的第二个选择是拥有一个只定义get访问器的接口。

public interface IMpi
{
    int Id { get; }
}
public class Mpi : IMpi
{
    public int Id { get; set; }
}

在此模型中,"基类"使用Mpi对象,"模块"类使用IMpi对象。它们是同一个实例,但模块同样不知道Id属性有一个set方法。

假设您有:

var modules = from file in Directory.GetFiles(path, "*.dll").AsParallel()
              from type in Assembly.LoadFile(file).GetTypes().AsParallel()
              where !type.IsInterface && typeof(Module).IsAssignableFrom(type)
              select (Module)Activator.CreateInstance(type);

然后你声明你的模块基类:

public abstract class Module
{
    public abstract Mpi Mpi { get; set; } // to inherit you must implement getter (you don't need it) and setter (what you're asking about)
    public abstract void Main(); // to inherit you must implement too
}

使用:

Mpi mpi = new Mpi();
foreach (Module m in modules)
{
     m.Mpi = mpi;
     m.Main();
}

另一个解决方案。如果基类haы是一个无参数的构造函数,它总是被调用的。在里面,你可以分配一个只能由基类写入的变量:

public abstract class Module
{
    protected Module()
    {
        this.Mpi = new Mpi();
    }
    protected Mpi Mpi { get; private set; } // getter is visible to children, setter only for class itself
}