gpt4 book ai didi

c# - 将 set 访问器添加到类中的属性,该类派生自只有一个 get 访问器的抽象类

转载 作者:可可西里 更新时间:2023-11-01 03:11:30 24 4
gpt4 key购买 nike

我有一个抽象类, AbsClass 实现一个接口(interface), IClass . IClass 有几个属性只有 Get 访问器。 AbsClass 实现 的属性IClass 作为要在派生自 的类中定义的抽象属性AbsClass .

所以所有派生自 的类AbsClass 还需要满足 IClass 通过与 Get 访问器具有相同的属性。但是,在某些情况下,我希望能够向来自 的属性添加 set 访问器。 IClass .然而,如果我尝试覆盖 中的抽象属性AbsClass 使用 set accessor 我收到此错误

ConcClassA.Bottom.Set 无法覆盖,因为 AbsClass.Bottom 没有可覆盖的 set 访问器

ConcClassA 以下。

如果我有一个仅实现 的类IClass 接口(interface),但不是从 AbsClass 继承然后我可以添加一个没有问题的 set 访问器。见 ConcClassB 以下。

我可以在 AbsClass 的每个派生中实现 IClass,而不是直接为 AbsClass 实现。然而我从我的设计中知道,每个 AbsClass 也需要是一个 IClass,所以我宁愿在层次结构中指定更高的位置。

public interface IClass
{
double Top
{
get;
}
double Bottom
{
get;
}
}

abstract class AbsClass:IClass
{
public abstract double Top
{
get;
}

public abstract double Bottom
{
get;
}
}



class ConcClassA : AbsClass
{
public override double Top
{
get { return 1; }
}

public override double Bottom
{
get { return 1; }

//adding a Set accessor causes error:
//ConcClassA.Bottom.Set cannot override because AbsClass.Bottom does not have an overridable set accessor

//set { }
}

}

class ConcClassB : IClass
{
public double Top
{
get { return 1; }
//added a set accessor to an interface does not cause problem
set { }
}
public double Bottom
{
get { return 1; }
}
}

更新

所以我认为如果我准确地解释我想要做的事情而不是使用抽象的例子,这会更有意义。我在一家建筑公司工作,这些是与建筑设计项目相关的业务对象。

我有一个抽象类 RhNodeBuilding 代表项目中的一种建筑类型。 中定义了一些通用功能,例如拥有楼层的能力。 RhNodeBuilding . RhNodeBuilding 还从另一个抽象类继承,使其成为更大的项目树结构的一部分。

RhNodeBuilding 从接口(interface)实现 IBuilding 它定义了所有建筑物都应该能够提供的许多只读属性,例如 TopElevation , 底部海拔 , 高度 , 楼层数 等等。请记住,还有其他建筑类型并非源自 RhNodeBuilding ,但仍需实现 IBuilding .

现在我有两种派生自 的类型。 RhNodeBuilding : 大众建筑 足印建筑 . 大众建筑 由用户创建的 3D 形状定义。该形状具有 TopElevation 和一个 底部海拔 应该可以通过相应的属性访问,但是您不能通过更改属性来编辑 3D 体积。

足印建筑另一方面,由闭合曲线和挤出该曲线的高度范围定义。因此,该类不仅应该能够返回当前的高度,而且还应该能够更改这些高度以重新定义高度范围。

所以总结一下。所有建筑物( IBuildings )都需要能够返回 TopElevation 底部海拔 ,但并非所有建筑物都应允许 TopElevation 底部海拔 要直接设置。全部 RhNodeBuildings IBuildings ,以及派生自 的类RhNodeBuilding 可能需要也可能不需要直接设置 TopElevation 底部海拔 .
public interface IBuilding
{
double Top
{
get;
}
double Bottom
{
get;
}
}

abstract class RhNodeBuilding:IBuilding
{
public abstract double Top
{
get;
}

public abstract double Bottom
{
get;
}
}



class MassBuilding: AbsClass
{

//mass building only returns Top and Bottom properties so it works fine
public override double Bottom
{
get { return 1; }
}

public override double Top
{
get { return 1; }
}

}


class FootPrintBuilding: AbsClass
{
//Top and Bottom of FootPrintBuilding can both be retrieved and set
public override double Top
{
get { return 1; }
//adding a Set accessor causes error:
//cannot override because RhNodeBuilding.Top does not have an overridable set accessor

//set { }
}

public override double Bottom
{
get { return 1; }

//adding a Set accessor causes error:
//cannot override because RhNodeBuilding.Bottom does not have an overridable set accessor

//set { }
}

}

现在看来最好的选择是没有 RhNodeBuilding 实现 IBuilding ,而是拥有从 派生的每个类RhNodeBuilding 实现 IBuilding。这样我就可以从 定义属性IBuilding 直接而不是作为覆盖。
abstract class AltRhNodeBuilding
{
public abstract double Top
{
get;
}
}


class AltFootPrintBuilding: IClass
{
public override double Top
{
get { return 1; }

//Can't add set access to overridden abstract property
set { }
}

//No problem adding set accessor to interface property
public double Bottom
{
get { return 1; }
set { }
}
}

最佳答案

这是因为属性不是真正虚拟的 - 它们的访问器方法是。因此,您不能覆盖 set如果基类中没有。

您可以做的是覆盖和隐藏基类实现,并提供您自己的新读/写属性。如果不在层次结构中引入额外的类,我不知道有什么方法可以做到这一点:

class AbsClassB : AbsClass
{
public override double Top { get { return ((ConcClassB)this).Top } }
public override double Bottom { get { return ((ConcClassB)this).Bottom } }
}


class ConcClassB : AbsClassB
{
new public double Top
{
get { ... }
set { ... }
}

new public double Bottom
{
get { ... }
set { ... }
}
}

更好的想法是在 AbsClass 中定义一个 protected 虚拟方法。 ,并实现 Top.getBottom.get就那个方法而言。然后您可以直接在 ConcClassB 中覆盖该方法,并隐藏属性,无需额外的类:
abstract class AbsClass : IClass
{
public double Top
{
get { return GetTop(); }
}

public double Bottom
{
get { return GetBottom(); }
}

protected abstract double GetTop();

protected abstract double GetBottom();
}

class ConcClassB : AbsClass
{
new public double Top
{
get { ... }
set { ... }
}

new public double Bottom
{
get { ... }
set { ... }
}

protected override double GetTop()
{
return Top;
}

protected override double GetBottom()
{
return Bottom;
}
}

关于c# - 将 set 访问器添加到类中的属性,该类派生自只有一个 get 访问器的抽象类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1169571/

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