Lui*_*ipe 39 .net c# inheritance covariance
据我所知,在C#2.0中无法执行以下操作
public class Father
{
public virtual Father SomePropertyName
{
get
{
return this;
}
}
}
public class Child : Father
{
public override Child SomePropertyName
{
get
{
return this;
}
}
}
Run Code Online (Sandbox Code Playgroud)
我通过在派生类中将属性创建为"new"来解决问题,但当然这不是多态的.
public new Child SomePropertyName
Run Code Online (Sandbox Code Playgroud)
2.0中有什么解决方案吗?3.5中解决此问题的任何功能如何?
Mar*_*ell 42
您可以重新声明(新),但不能同时重新声明和覆盖(使用相同的名称).一种选择是使用受保护的方法来隐藏细节 - 这允许同时进行多态和隐藏:
public class Father
{
public Father SomePropertyName
{
get {
return SomePropertyImpl();
}
}
protected virtual Father SomePropertyImpl()
{
// base-class version
}
}
public class Child : Father
{
public new Child SomePropertyName
{
get
{ // since we know our local SomePropertyImpl actually returns a Child
return (Child)SomePropertyImpl();
}
}
protected override Father SomePropertyImpl()
{
// do something different, might return a Child
// but typed as Father for the return
}
}
Run Code Online (Sandbox Code Playgroud)
Ale*_*man 26
由于类型安全问题,这在任何.NET语言中都是不可能的.在类型安全的语言中,您必须为返回值和参数的逆变提供协方差.拿这个代码:
class B {
S Get();
Set(S);
}
class D : B {
T Get();
Set(T);
}
Run Code Online (Sandbox Code Playgroud)
对于这些Get
方法,协方差意味着T
必须是S
或来自的类型S
.否则,如果你有一个类型对象的引用D
存储在一个类型的变量中B
,当你调用时,B.Get()
你不会得到一个可以表示为对象S
类型系统的对象.
对于这些Set
方法,逆变意味着T
必须是S
或S
来自的类型.否则,如果你有一个类型的对象的引用D
存储在一个类型的变量中B
,当你调用时B.Set(X)
,where X
类型S
但不是类型T
,D::Set(T)
将获得一个它没有预期的类型的对象.
在C#中,有意识地决定在重载属性时不允许更改类型,即使它们只有一个getter/setter对,因为否则会有非常不一致的行为("你的意思是,我可以更改类型一个有吸气剂,但没有吸气剂和二传手?为什么不呢?!?" - 匿名替代宇宙新手).
Kei*_*ith 11
不,但您可以在2及以上版本中使用泛型:
public class MyClass<T> where T: Person
{
public virtual T SomePropertyName
{
get
{
return ...;
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后父亲和孩子是同一类的通用版本
Mar*_*ese 10
从C# 9开始,支持返回类型协方差。这是从该链接复制的基本示例:
class Compilation ...
{
public virtual Compilation WithOptions(Options options)...
}
class CSharpCompilation : Compilation
{
public override CSharpCompilation WithOptions(Options options)...
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
27485 次 |
最近记录: |