当前位置:  开发笔记 > 编程语言 > 正文

我可以用派生类型覆盖吗?

如何解决《我可以用派生类型覆盖吗?》经验,为你挑选了4个好方法。

据我所知,在C#2.0中无法执行以下操作

public class Father
{
    public virtual Father SomePropertyName
    {
        get
        {
            return this;
        }
    }
}

public class Child : Father
{
    public override Child SomePropertyName
    {
        get
        {
            return this;
        }
    }
}

我通过在派生类中将属性创建为"new"来解决问题,但当然这不是多态的.

public new Child SomePropertyName

2.0中有什么解决方案吗?3.5中解决此问题的任何功能如何?



1> Marc Gravell..:

您可以重新声明(新),但不能同时重新声明和覆盖(使用相同的名称).一种选择是使用受保护的方法来隐藏细节 - 这允许同时进行多态和隐藏:

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
    }
}


我一直都在使用这个技巧,我讨厌它:)

2> Alex Lyman..:

由于类型安全问题,这在任何.NET语言中都是不可能的.在类型安全的语言中,您必须为返回值和参数的逆变提供协方差.拿这个代码:

class B {
    S Get();
    Set(S);
}
class D : B {
    T Get();
    Set(T);
}

对于这些Get方法,协方差意味着T必须是S或来自的类型S.否则,如果你有一个类型对象的引用D存储在一个类型的变量中B,当你调用时,B.Get()你不会得到一个可以表示为对象S类型系统的对象.

对于这些Set方法,逆变意味着T必须是SS来自的类型.否则,如果你有一个类型的对象的引用D存储在一个类型的变量中B,当你调用时B.Set(X),where X类型S但不是类型T,D::Set(T)将获得一个它没有预期的类型的对象.

在C#中,有意识地决定在重载属性时不允许更改类型,即使它们只有一个getter/setter对,因为否则会有非常不一致的行为("你的意思是,我可以更改类型一个有吸气剂,但没有吸气剂和二传手?为什么不呢?!?" - 匿名替代宇宙新手).


您的观点是有效的,但该示例具有只读属性.
你引入了一个aritficial约束,`Get`必须返回与'Set`接收的相同的`T`.没有这种约束,你的论点就不成立.请参阅此答案以获得更好的解释:http://stackoverflow.com/questions/5709034/does-c-sharp-support-return-type-covariance

3> Keith..:

不,但您可以在2及以上版本中使用泛型:

public class MyClass where T: Person
{
    public virtual T SomePropertyName
    {
        get
        {
            return  ...;
        }
    }
}

然后父亲和孩子是同一类的通用版本



4> dalle..:

来自维基百科:

在C#编程语言中,在该语言的2.0版本中添加了对委托的返回类型协方差和参数逆变的支持.方法覆盖不支持协方差或逆变.

尽管如此,它没有明确说明关于属性的协方差.


属性只是两个方法(set_Foo和get_Foo)
推荐阅读
吻过彩虹的脸_378
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有