C# 覆盖获取,但未设置

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2026546/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 22:49:14  来源:igfitidea点击:

Override get, But not set

c#

提问by Graviton

I have an abstract class that defines a get, but not set, because as far as that abstract class is concerned, it needs only a get.

我有一个定义 a 的抽象类get,但没有定义set,因为就该抽象类而言,它只需要一个get.

public abstract BaseClass
{
  public abstract double MyPop
  {get;}
}

However, in some of the derive class, I need a setproperty, so I am looking at this implementation

但是,在一些派生类中,我需要一个set属性,所以我在看这个实现

public class DClass: BaseClass
{
  public override double MyPop
  {get;set;}
}

The problem is, I got a compilation error, saying that

问题是,我得到一个编译错误,说

*.set: cannot override because *. does not have an overridable set accessor.

*.set: 不能覆盖,因为 *. 没有可覆盖的 set 访问器。

Even though I think that the above syntax is perfectly legitimate.

尽管我认为上述语法是完全合法的。

Any idea on this? Workaround, or why this is so?

对此有什么想法吗?解决方法,或者为什么会这样?

Edit: The only approach I can think of is to put both getand setas in the abstract class, and let the subclass throws a NotImplementedExceptionif setis called and it's not necessary. That's something I don't like, along with a special setter method.

编辑:我能想到的唯一方法是将getand setas 都放在抽象类中,让子类抛出NotImplementedExceptionifset被调用,这不是必需的。这是我不喜欢的东西,还有一个特殊的 setter 方法

采纳答案by Brian

New in C# 6.0:

C# 6.0 中的新功能:

If you are only calling the setter within your constructor, you can resolve this problem using read-only properties.

如果您仅在构造函数中调用 setter,则可以使用只读属性解决此问题。

void Main()
{
    BaseClass demo = new DClass(3.6);
}

public abstract class BaseClass
{
    public abstract double MyPop{ get; }
}

public class DClass : BaseClass
{
    public override double MyPop { get; }
    public DClass(double myPop) { MyPop = myPop;}
}

回答by Pondidum

Why not just have a property in the base class that has a private setter, then in your subclass that needs the setter, override it and make it public.

为什么不在基类中拥有一个具有私有 setter 的属性,然后在需要该 setter 的子类中,覆盖它并使其公开。

回答by Rune Grimstad

You cannot override the set accessor since the base class has no set accessor defined.

您不能覆盖 set 访问器,因为基类没有定义 set 访问器。

What you can do is use the newkeyword to hide the base classes implementation, but that may not be what you want.

您可以做的是使用new关键字来隐藏基类实现,但这可能不是您想要的。

回答by Codesleuth

EDIT:

编辑:

OK I may have been hasty with this response, but I've given it some more thought now.

好吧,我可能对这个回应很仓促,但我现在已经考虑了更多。

Do you have to use an abstract base class? If it's not required, try this:

你必须使用抽象基类吗?如果不需要,请尝试以下操作:

public interface ISomeRelevantName
{
    double MyPop { get; }
}

public class DClass : ISomeRelevantName
{
    public double MyPop { get; set; }
}

回答by David M

One possible answer would be to override the getter, and then to implement a separate setter method. If you don't want the property setter to be defined in the base, you don't have many other options.

一个可能的答案是覆盖 getter,然后实现一个单独的 setter 方法。如果您不希望在基础中定义属性设置器,那么您没有很多其他选择。

public override double MyPop
{
    get { return _myPop; }
}

public void SetMyPop(double value)
{
    _myPop = value;
}

回答by Laurent Etiemble

It is not possible to do what you want. You have to define the setter in the abstract property, otherwise you won't be able to override it properly.

做你想做的事是不可能的。您必须在抽象属性中定义 setter,否则您将无法正确覆盖它。

The only case I know where a getter is defined and a getter/setter are implemented is by using an interface:

我知道在何处定义了 getter 并实现了 getter/setter 的唯一情况是使用接口:

public interface IBaseInterface
{
    double MyPop { get; }
}

public class DClass : IBaseInterface
{
    public double MyPop { get; set; }
}

回答by Darin Dimitrov

public abstract class BaseClass
{
    public abstract double MyPop { get; }
}

public class DClass: BaseClass
{
    private double _myPop = 0;
    public override double MyPop 
    {
        get { return _myPop; }
    }

    // some other methods here that use the _myPop field
}

If you need to set the property from outside DClassthen maybe it would be better to put the setter into the base class.

如果您需要从外部设置属性,DClass那么将 setter 放入基类可能会更好。

回答by mattjames

Are you sure that doing what you are trying to do would be a good design if you found a way to do it?

如果你找到了一种方法,你确定做你想做的事情会是一个很好的设计吗?

It would allow objects of the subclass to make state changes that objects of the parent class can not make. Wouldn't that violate the Liskov Substitution Principle?

它将允许子类的对象进行父类对象无法进行的状态更改。这不会违反里氏替换原则吗?

回答by gotopie

You could do something like this:

你可以这样做:

abstract class TestBase { public abstract int Int { get; } }

abstract class TestBase { public abstract int Int { get; } }

class TestDerivedHelper : TestBase
{
    private int _Int;
    public override int Int
    {
        get
        {
            return _Int;
        }
    }

    protected void SetInt(int value)
    {
        this._Int = value;
    }
}

class TestDerived : TestDerivedHelper
{
    public new int Int
    {
        get { return base.Int; }
        set { base.SetInt(value); }
    }
}
class TestDerivedHelper : TestBase
{
    private int _Int;
    public override int Int
    {
        get
        {
            return _Int;
        }
    }

    protected void SetInt(int value)
    {
        this._Int = value;
    }
}

class TestDerived : TestDerivedHelper
{
    public new int Int
    {
        get { return base.Int; }
        set { base.SetInt(value); }
    }
}

Using TestDerived will have the functionality you're looking for. The only drawback I can see from this method is that you have to implement every abstract method in TestDerivedHelper, but it gives you more control later.

使用 TestDerived 将具有您正在寻找的功能。我从这个方法中看到的唯一缺点是你必须在 TestDerivedHelper 中实现每个抽象方法,但它给你更多的控制权。

Hope this helps. ;)

希望这可以帮助。;)

回答by herzmeister

If BaseClassis in your own codebase, then you can do:

如果BaseClass在您自己的代码库中,那么您可以执行以下操作:

abstract public class BaseClass
{
    abstract public double MyPop { get; protected set; }
}

public class DClass : BaseClass
{
    private double _myProp;
    public override double MyProp
    {
        get { return _myProp; }
        protected set { _myProp = value; }
    }
}

EDIT: You can then go make a public method in DClass SetMyProp(double myProp)or the like. The class design for your domain model should be clear about or speak for itself why you can't set the property directly in the base class and why you can do so in the derived one.

编辑:然后您可以在 DClassSetMyProp(double myProp)等中创建一个公共方法。域模型的类设计应该清楚说明或说明为什么不能直接在基类中设置属性以及为什么可以在派生类中这样做。

回答by Thiago Romam

Siege

围城

abstract class TestBase
{
    public abstract int Int { get; }
}

class TestDerivedHelper : TestBase
{
    private int _Int;
    public override int Int
    {
        get
        {
            return _Int;
        }
    }

    protected void SetInt(int value)
    {
        this._Int = value;
    }
}

class TestDerived : TestDerivedHelper
{
    public new int Int
    {
        get { return base.Int; }
        set { base.SetInt(value); }
    }
}

Using TestDerived will have the functionality you're looking for. The only drawback I can see from this method is that you have to implement every abstract method in TestDerivedHelper, but it gives you more control later.

使用 TestDerived 将具有您正在寻找的功能。我从这个方法中看到的唯一缺点是你必须在 TestDerivedHelper 中实现每个抽象方法,但它给你更多的控制权。

I use this approach and works very well for me. Also, I made my "TestDerivedHelper" class abstract too, then all the methods must be implemented on "TestDerived" class.

我使用这种方法并且非常适合我。此外,我也将“TestDerivedHelper”类抽象化,然后所有方法都必须在“TestDerived”类上实现。