我在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; }
    }
}


我个人更喜欢第一种方法。

10-08 08:28
查看更多