我在C#基类上有一个枚举属性,我想在所有派生类上实现只读,除了一个(我需要该属性进行读写)。< / p>
我的枚举声明如下:
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
关键字(即。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
两个可见性属性值不同,这不是我想要的。
我最终通过声明属性来解决这个问题:
sealed class FooDataView : DataViewBase
{
public new Visibility Visibility
{
get { return base.Visibility; }
set { base.Visibility = value; }
}
}
这可以确保两个可见性属性保持同步&#34;同步&#34;。
然而,在完成所有这些之后,我想知道是否有另一种方法来完成我想要的东西(根据问题标题),因为我的解决方案看起来有些不雅。我无法想到任何其他明显的解决方案。
答案 0 :(得分:1)
然而,在完成所有这些之后,我想知道是否还有另一个 给出了完成我想要的方式(根据问题标题) 我的解决方案似乎有些不雅。我无法想到任何其他人 明显的解决方案。
没有。没有其他解决方案。为什么要将属性更改为可在派生类中公开设置(似乎setter在基类中也应该是公共的)?也许你应该以其他方式公开这个功能。
答案 1 :(得分:1)
您可以创建一个访问setter的接口:
interface ISetVisibility {
Visibility Visibilty {set;}
}
class MyDerived : MyBase, ISetVisibility {
Visibility ISetVisibilty.Visibility { set {/* ... */ } }
}
现在,在您的主要班级中,您可以使用以下内容:
((ISetVisibility) myDerived).Visibility = Visibilty.Shared;
答案 2 :(得分:1)
这两个怎么样:
<强> 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; }
}
}
我个人更喜欢第一种方法。