我在C#基类上有一个枚举属性,我希望在除一个类(我需要对该属性进行读写)之外的所有派生类上有效地只读。
我的枚举声明如下:
enum Visibility { Public, Shared, Private }
(顺便说一下,枚举成员名称与C#可见性修饰符无关!)
最初,我认为我可以像这样在基类上声明属性:
abstract class DataViewBase
{
public Visibility Visibility { get; protected set; }
}
然后更改派生类上的声明:
sealed class FooDataView : DataViewBase
{
public Visibility Visibility { get; set; }
}
因此将设置器公开,但是我应该意识到这隐藏了基本的Visibility属性并生成了编译器警告。添加
new
关键字(即public new Visibility ...
)摆脱了警告,但是FooDataView上的属性实际上变成了一个全新的属性,与基类上的属性没有任何关系。因此,如果我这样做: var foo = new FooDataView();
foo.Visibility = Visibility.Shared;
Console.WriteLine(foo.Visibility); // Shared
var casted = (DataViewBase) foo;
Console.WriteLine(casted.Visibility); // Public
两个Visibility属性值不同,这不是我想要的。
我最终通过这样声明属性来解决此问题:
sealed class FooDataView : DataViewBase
{
public new Visibility Visibility
{
get { return base.Visibility; }
set { base.Visibility = value; }
}
}
这样可以确保两个“可见性”属性保持“同步”。
但是,在完成所有这些操作之后,我想知道是否还有另一种方法来完成我想要的工作(根据问题标题),因为我的解决方案似乎不太优雅。我想不出任何其他明显的解决方案。
最佳答案
那两个怎么样?
1.添加新方法
class FooDataView : DataViewBase
{
public void ChangeVisibility(Visibility visibility)
{
Visibility = visibility;
}
}
只需添加一个新的
ChangeVisibility()
方法。我认为这是最简单的。2.使用界面:
public interface IDataView
{
Visibility Visibility { get; }
}
public class DataView : IDataView
{
public Visibility Visibility { get; set; }
}
public class PrivateDataView : IDataView
{
public Visibility Visibility
{
get { return Visibility.Private; }
}
}
我个人更喜欢第一种方法。