是否可以在 属性 的定义中同时使用 'new' 和 'override'?
Is it possible to use both 'new' and 'override' in a definition of property?
我试图解决我的应用程序中的继承问题。基本上是这样的:
interface IAbcBase
{
int? Value { get; }
}
interface IAbc : IAbcBase
{
new int Value { get; }
}
class BaseA : IAbcBase
{
public virtual int? Value => (this as A)?.Value;
}
class A : BaseA, IAbc
{
// public override int? Value => 4; // line A
public new int Value => 4; // line B
}
我想从 BaseA
中隐藏 属性 Value
,并用 A
上的不可空 属性 替换它。但同时我也希望能够重写 属性 Value
以便为 Value
提供更有效的定义,以防我将其分配给 BaseA
类型的变量。
BaseA a = new A();
var b = a.Value; // b is int? which is fine. But ineffective definition was used instead of line A
是否有可能以某种方式覆盖 属性 并同时隐藏它(即取消注释 A 和 B 行)?在我的实际应用程序中,base class 的定义并不是那么简单,我很乐意提供更有效的定义并隐藏该值。
解决方案可能是不从 base 中隐藏成员,而是使用另一个名称。例如 ValueNotNull
并将覆盖的方法标记为已过时。但这并不是那么简单,因为我无法修改接口 IAbcBase
和 IAbc
中的成员。我不喜欢这个解决方案,因为 IAbc
的实现必须是显式的,所以我可以覆盖 BaseA
中的成员,然后我无法在 [=18= 上使用名称 Value
] 这就是我想要的,因为它基本上是不可为 null 的 Value
on BaseA
.
希望我能很好地描述我的问题。如果需要任何细节,我会编辑
/// 编辑:
如果允许 A 行和 B 行的定义,我被要求提供用例示例。在我的实际应用中,我有以下定义(简化):
internal sealed class StandardDefinition : Definition
{
public Definition Previous { get; }
public new int NodesCount { get; }
}
internal sealed class RootDefinition : Definition
{
}
internal abstract class Definition
{
public int? NodesCount => (this as StandardDefinition)?.NodesCount;
}
根节点基本上是国际象棋分析的起始位置,不一定是标准的起始位置。 NodesCount 是用于分析此移动的节点数。这是我没有的根位置,因为我从来没有从任何分析中得到起始位置,所以没有什么可以 return (有更多类似的属性,我简化了很多)。
我主要使用 Definition
的变量,除了代码中的一个地方,在分析完成后我得到了 StandardDefinition
。因此,使用 NodesCount
和其他类似属性的大多数无效定义,而不是使用 StandardDefinition
中的定义。这就是为什么我希望能够覆盖,因为大多数实例显然都是 StandardDefinition
类型。只有很少的 RootDefinition
。大多数针对 null 的强制转换和测试是完全没有必要的。分析位置后,我得到 StandardDefinition
,现在我希望能够隐藏可为空的旧定义,并提供仅 returns 不可为空节点计数的定义用于分析此位置。再次避免所有不必要的转换等
不,基本上,如果您指的是 A
上的 public API。唯一的解决办法是引入一个额外的层:
abstract class AlmostA : BaseA
{
public override int? Value => GetValue();
protected int GetValue() => 4;
}
class A : AlmostA, IAbc
{
public new int Value => GetValue();
}
如果你的意思只是为了满足IAbc
界面,那么"explicit interface implementation"就是你的朋友:
class A : BaseA, IAbc
{
private int GetValue() => 4;
public override int? Value => GetValue();
int IAbc.Value => GetValue();
}
我试图解决我的应用程序中的继承问题。基本上是这样的:
interface IAbcBase
{
int? Value { get; }
}
interface IAbc : IAbcBase
{
new int Value { get; }
}
class BaseA : IAbcBase
{
public virtual int? Value => (this as A)?.Value;
}
class A : BaseA, IAbc
{
// public override int? Value => 4; // line A
public new int Value => 4; // line B
}
我想从 BaseA
中隐藏 属性 Value
,并用 A
上的不可空 属性 替换它。但同时我也希望能够重写 属性 Value
以便为 Value
提供更有效的定义,以防我将其分配给 BaseA
类型的变量。
BaseA a = new A();
var b = a.Value; // b is int? which is fine. But ineffective definition was used instead of line A
是否有可能以某种方式覆盖 属性 并同时隐藏它(即取消注释 A 和 B 行)?在我的实际应用程序中,base class 的定义并不是那么简单,我很乐意提供更有效的定义并隐藏该值。
解决方案可能是不从 base 中隐藏成员,而是使用另一个名称。例如 ValueNotNull
并将覆盖的方法标记为已过时。但这并不是那么简单,因为我无法修改接口 IAbcBase
和 IAbc
中的成员。我不喜欢这个解决方案,因为 IAbc
的实现必须是显式的,所以我可以覆盖 BaseA
中的成员,然后我无法在 [=18= 上使用名称 Value
] 这就是我想要的,因为它基本上是不可为 null 的 Value
on BaseA
.
希望我能很好地描述我的问题。如果需要任何细节,我会编辑
/// 编辑: 如果允许 A 行和 B 行的定义,我被要求提供用例示例。在我的实际应用中,我有以下定义(简化):
internal sealed class StandardDefinition : Definition
{
public Definition Previous { get; }
public new int NodesCount { get; }
}
internal sealed class RootDefinition : Definition
{
}
internal abstract class Definition
{
public int? NodesCount => (this as StandardDefinition)?.NodesCount;
}
根节点基本上是国际象棋分析的起始位置,不一定是标准的起始位置。 NodesCount 是用于分析此移动的节点数。这是我没有的根位置,因为我从来没有从任何分析中得到起始位置,所以没有什么可以 return (有更多类似的属性,我简化了很多)。
我主要使用 Definition
的变量,除了代码中的一个地方,在分析完成后我得到了 StandardDefinition
。因此,使用 NodesCount
和其他类似属性的大多数无效定义,而不是使用 StandardDefinition
中的定义。这就是为什么我希望能够覆盖,因为大多数实例显然都是 StandardDefinition
类型。只有很少的 RootDefinition
。大多数针对 null 的强制转换和测试是完全没有必要的。分析位置后,我得到 StandardDefinition
,现在我希望能够隐藏可为空的旧定义,并提供仅 returns 不可为空节点计数的定义用于分析此位置。再次避免所有不必要的转换等
不,基本上,如果您指的是 A
上的 public API。唯一的解决办法是引入一个额外的层:
abstract class AlmostA : BaseA
{
public override int? Value => GetValue();
protected int GetValue() => 4;
}
class A : AlmostA, IAbc
{
public new int Value => GetValue();
}
如果你的意思只是为了满足IAbc
界面,那么"explicit interface implementation"就是你的朋友:
class A : BaseA, IAbc
{
private int GetValue() => 4;
public override int? Value => GetValue();
int IAbc.Value => GetValue();
}