类的只读版本,仅用于非固有类
本文关键字:用于 只读 版本 | 更新日期: 2023-09-27 17:52:55
我需要一个类的受保护属性版本。这意味着外部类不能更改值,但固有类可以。
这是一个示例代码,正如您所看到的,我使用的是一个"臭布尔解决方案"。我应该如何以更优雅的方式做到这一点?我希望有一些好的模式来解决这个问题。
由于有许多"受保护集"答案而编辑:
如果这样做,我将无法在非固有类中设置类属性,并且在构造函数期间设置IsReadOnly属性和值将毫无用处。
public class Foo1
{
protected bool smellyBoolSolution = false;
public bool IsReadOnly { get; private set; }
private int x;
public int X
{
get { return x; }
set
{
CheckCanWrite();
x = value;
}
}
public Foo1(bool isReadOnly)
{
IsReadOnly = isReadOnly;
}
private void CheckCanWrite()
{
if (IsReadOnly && !smellyBoolSolution)
throw new InvalidOperationException("Class is read only.");
}
}
public class Foo2 : Foo1
{
public Foo2()
: base(true)
{
}
public void DoStuff()
{
int newX = 1;
//.... calculates new x
//Oh, using the smelly bool solution I can change my base class properties
base.smellyBoolSolution = true;
base.X = newX;
base.smellyBoolSolution = false;
}
}
//Usage
public class Foo3
{
public void DoStuff()
{
//Foo1 in writable version
Foo1 f = new Foo1(false);
f.X = 1;
//Foo2 inherents Foo1 and only Foo2 can change X
Foo2 f2 = new Foo2();
f2.X = 1; //Exception here.
}
}
使用受保护的字段启用从基类和继承类的写入,公开公共只读属性:
public class A
{
protected string FooField;
public string Foo { get { return FooField; } }
public A()
{
FooField = "A";
}
}
public class B : A
{
public B()
: base()
{
FooField = "B";
}
}
你甚至可以使用自动属性:
public class A
{
public string Foo { get; protected set; }
public A()
{
Foo = "A";
}
}
public class B : A
{
public B()
: base()
{
Foo = "B";
}
}
另请参阅限制访问器可访问性(C#编程指南(。
private int x
int X
{
public get { return x; }
protected set { x = value; }
}
甚至更短的
int X { public get; protected set; }
这两个解决方案并不完全相同,因为第一个解决方案使用显式实现的属性,而第二个解决方案则使用自动实现的属性。
您试图做的事情违反了Liskov替换原则,应该避免。
通过继承Foo1
,类Foo2
承诺遵守超类Foo1
公开的接口。即,在Foo1
上操作的方法不必关心实际接收的输入是Foo1
还是Foo2
。这两种类型都公开了相同的接口,因此可以以统一的方式进行操作。
这就是为什么除了重新思考你的设计之外,没有优雅的解决方案来解决你的问题。