如何使派生类中的只读属性可写?

时间:2015-04-23 10:51:16

标签: c# inheritance

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

然而,在完成所有这些之后,我想知道是否有另一种方法来完成我想要的东西(根据问题标题),因为我的解决方案看起来有些不雅。我无法想到任何其他明显的解决方案。

3 个答案:

答案 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; }
    }
}

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