我需要一个类的受保护属性版本。意味着外部类不能改变值,但固有类可以。
以下是一个示例代码,您可以看到,我正在使用" smelly bool解决方案"。我该怎样以更优雅的方式做到这一点?我希望这个问题有一些很好的模式解决方案。
编辑由于很多"受保护的设置"答案:
这样做我将无法在非固有类中设置类属性,并且构造函数中的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.
}
}
答案 0 :(得分:1)
使用受保护的字段来启用从基类和继承类的写入,公开一个公共只读属性:
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";
}
}
另见Restricting Accessor Accessibility (C# Programming Guide)。
答案 1 :(得分:0)
private int x
int X
{
public get { return x; }
protected set { x = value; }
}
甚至更短
int X { public get; protected set; }
这两个解决方案并不完全相同,因为第一个解决方案使用显式实现的属性,第二个解决方案自动实现属性。
答案 2 :(得分:0)
您要做的是违反Liskov substitution principle,应该避免。
继承自<h4 data-bind="html:Product() + '<small>' + Price() + '</small>'"></h4>
,类Foo1
承诺遵守超类Foo2
公开的接口。即在Foo1
上运行的方法不必关心所接收的输入是实际上是Foo1
还是Foo1
。两种类型都暴露相同的接口,因此可以统一的方式进行操作。
这就是为什么除了重新思考你的设计之外没有优雅的解决方案。