我在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; }
}
从而使setter公开,但我应该意识到这隐藏了基础 Visibility 属性并生成编译器警告 . 添加 new
关键字(即.2778871_)可以消除警告,但 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; }
}
}
这可确保保留两个 Visibility 属性"in-sync" .
然而,在完成所有这些之后,我想知道是否有另一种方法来完成我想要的东西(根据问题 Headers ),因为我的解决方案似乎有点不优雅 . 我想不出任何其他明显的解决方案 .
3 回答
这两个怎么样:
1. Add A New Method
只需添加一个新的
ChangeVisibility()
方法 . 我认为这是最简单的 .2. Use Interface:
我个人更喜欢第一种方法 .
不,没有其他解决方案 . 为什么要将属性更改为可在派生类中公开设置(似乎setter在基类中也应该是公共的)?也许您应该以其他方式公开此功能 .
您可以创建一个访问setter的接口:
现在在您的主类中,您可以使用以下内容: