c#代码设计:1个库,2个项目使用它(但一个是只读的)

本文关键字:一个 只读 代码 1个库 项目 2个 | 更新日期: 2023-09-27 18:10:34

想象一下,有3个项目。一个库和两个可执行文件

两个程序都使用库。项目1在其中创建了许多类的实例,并使用序列化器保存它们。项目2,加载它们,但不应该对它们做任何更改。

因此,对于项目2它应该是只读的,但是项目1应该对它有完全的访问权限。我该如何设计呢?

假设库中有这样一个类:

public string Name { get; private set;} 
public int Age { get; private set;}
public Person(string Name, int Age)
{
   this.Name = Name;
   this.Age = Age;
}

对于项目2来说,这将是完美的,因为项目2将其用作只读。

但是对于项目1来说非常烦人,因为只要它要改变类中的一个属性,它就必须创建一个完整的新实例。拥有2个属性时并不令人讨厌,但拥有10个属性时就很烦人了。项目2甚至会很高兴看到这些值是const。

最好的设计方法是什么?

c#代码设计:1个库,2个项目使用它(但一个是只读的)

接口是做这些事情的方式。

public IPerson
{
    string Name { get; }
    int Age { get; }
}

In Project1:

public class Person : IPerson
{
    public string Name { get; set;} 
    public int Age { get; set;}
    public Person(string name, int age)
    {
       this.Name = name;
       this.Age = age;
    }
}
在Project2:

public class Person : IPerson
{
    public readonly string _name;
    public string Name { get { return _name; } } 
    private readonly int _age;
    public int Age { get { return _age; } }
    public Person(string name, int age)
    {
       this._name = name;
       this._age = age;
    }
}

注意,真正的不可变类使用只读字段而不是私有setter。
私有setter允许实例在创建后修改其状态,因此它不是真正的不可变实例。
而一个字段只能在构造函数中设置。

那么你可以通过扩展共享相同的方法:

public static class PersonExtensions
{
    public static string WhoAreYou(this IPerson person)
    {
        return "My name is " + person.Name + " and I'm " + person.Age + " years old.";
    }
}

条件编译可以做到这一点,只需在Visual Studio中创建新的构建配置并使用条件编译符号,然后包装所有可写语句,以便它们使用一种配置而不是另一种配置编译,例如:

public string Name { 
    get; 
#if WriteSupport
    private set;
#endif
} 
public int Age { 
    get; 
#if WriteSupport
    private set;
#endif
}
public Person(string Name, int Age)
{
   this.Name = Name;
   this.Age = Age;
}