gpt4 book ai didi

c# - 为一些(但不是所有)继承类引入 setter

转载 作者:太空狗 更新时间:2023-10-29 21:57:46 24 4
gpt4 key购买 nike

我很难在 C# 中实现一个在抽象基类中只有 getter 的属性,但我需要在其中一个中引入 setter派生类。


更新:有关此问题的一般示例的简短解释,see this question .选择的答案已经解释了为什么这在 C# 中目前是不可能的,但是,在我看来,还没有提供令人满意的解决方案。


我的类图概述如下所示:

Class diagram

我的目标是 TextElementStaticTextElementReferenceSource 这两个类应该有一个包含 getter 和 setter 的 Text 属性,而类 TextElementReferenceTarget 应该有一个只有 getter 的 Text 属性。我在引用所有这些对象时经常使用 ITextElement,我需要确保 ITextElement 接口(interface)只有一个 getter。此外,基类 TextElement 实现了很多通用代码,因此所有类都需要从该类继承。

我当前的代码如下所示:

接口(interface):ITextElement

public interface ITextElement
{
string Text { get; }
}

接口(interface):ITextElementUpdatable

public interface ITextElementUpdatable : ITextElement
{
new string Text { get; set; }
}

抽象类:TextElement (这是我的问题所在,下面解释)

public abstract class TextElement : ITextElement
{
// I want to mark this 'abstract', but that causes my problem
public virtual string Text
{
get
{
// NOTE: This should never be called
Debug.Fail("Called virtual Text getter that should never be called");
return default(string);
}
}
}

抽象类:TextElementUpdatable

public abstract class TextElementUpdatable : TextElement, ITextElementUpdatable
{
// Should have both a getter and a setter
public new virtual string Text { get; set; }
}

类:TextElementStatic

public class TextElementStatic : TextElementUpdatable
{
// Should have both a getter and a setter
// No Text property declaration
// Inherits Text property from TextElementUpdatable
}

类:TextElementReferenceSource

public class TextElementReferenceSource : TextElementUpdatable
{
// Should have both a getter and a setter
public override string Text
{
get { return _internalobject.Text; }
set { _internalobject.Text = value; }
}
}

类:TextElementReferenceTarget

public class TextElementReferenceTarget : TextElement
{
// Should ONLY have a getter
public override string Text
{
get { return _internalobject.Text; }
}
}

所以,我的问题是:我真的想在基类 TextElement 抽象中声明 Text 属性,因为它应该始终在派生类中实现(TextElementUpdatable、TextElementReferenceSource 和 TextElementReferenceTarget 都实现了这个属性)。但是,如果我尝试将该属性转换为 public abstract string Text { get; },然后我在 TextElementUpdatable 中收到错误,指出

TextElementUpdatable.Text hides the inherited property TextElement.Text

此外,如果我将 TextElementUpdatable 中的属性从 new 更改为 override,错误消息将替换为:

Cannot override because TextElement.Text does not have an overridable set accessor

现在,我可以回到 TextElement 并将属性更改为 public virtual string Text { get;私有(private)集; } 并收工,因为无论如何都不应该调用该方法(这基本上是我现在的解决方案)。但是,如果我或其他人稍后创建另一个派生类,我想强制我/他们实现文本属性,因此我宁愿将其标记为抽象,也不愿提供虚拟实现。

关于如何正确执行此操作的任何建议 - 即使它应该涉及大量重构?

我知道我可以将她的两个目标分开,提供一个仅具有 getter 的继承 Text 属性,然后在 中引入一个 SetText() 方法>ITextElementUpdatable 接口(interface)。但是,我想知道是否可以找到仅具有属性的良好解决方案。


另一个类似的问题,但没有任何答案我已经能够使用:C# - What should I do when every inherited class needs getter from base class, but setter only for ONE inherited class

最佳答案

这确实是一个令人兴奋的设计问题,但是.. 你必须使用 new 关键字这不是一个好的做法。尽量避开它们。当然,接口(interface)中的属性名称可以相同,但如果两者都由一个类实现(并且其中一个属性定义时没有 setter ),我们必须明确地实现它们。我们必须接受这些属性“冲突”。您可以引入抽象方法:

public abstract class TextElement : ITextElement
{
public string Text { get { return GetText(); } }

protected abstract string GetText();
}

public abstract class TextElementUpdatable : TextElement, ITextElementUpdatable
{
string ITextElementUpdatable.Text
{
get { return GetText(); }
set { SetText(value); }
}

protected abstract void SetText(string text);
}

关于c# - 为一些(但不是所有)继承类引入 setter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23833476/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com