从通用抽象类派生的类的C#方法重载问题

前端之家收集整理的这篇文章主要介绍了从通用抽象类派生的类的C#方法重载问题前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在研究一个项目,我有一个通用的抽象类型,它接受一个本身派生自抽象类型的类型参数.如果您想知道为什么我会这样做,请参阅 this question.

我在抽象类中定义的派生类中重载方法遇到了一个有趣的问题.这是一个代码示例:

public abstract class AbstractConverter<T,U>
    where U : AbstractConvertible
    where T : AbstractConverter<T,U>
{
    public abstract T Convert(U convertible);
}

public class DerivedConvertibleConverter : AbstractConverter<DerivedConvertibleConverter,DerivedConvertible>
{
    public DerivedConvertibleConverter(DerivedConvertible convertible)
    {
        Convert(convertible);
    }

    public override DerivedConvertibleConverter Convert(DerivedConvertible convertible)
    {
        //This will not be called
        System.Console.WriteLine("Called the most derived method");
        return this;
    }

    public DerivedConvertibleConverter Convert(Convertible convertible)
    {
        System.Console.WriteLine("Called the least derived method");
        return this;
    }
}

public abstract class AbstractConvertible {}

public class Convertible : AbstractConvertible {}

public class DerivedConvertible : Convertible {}

在上面的示例中,调用了抽象父级中不存在的Convert的重载(并且派生次数较少).我希望可以调用来自父类的派生程度最高的版本.

在尝试解决此问题时,我遇到了一个有趣的解决方案:

public abstract class AbstractConverter<U>
    where U : AbstractConvertible
{
    public abstract AbstractConverter<U> Convert(U convertible);
}

public class DerivedConvertibleConverter : AbstractConverter<DerivedConvertible>
{
    public DerivedConvertibleConverter(DerivedConvertible convertible)
    {
        Convert(convertible);
    }

    public override DerivedConvertibleConverter Convert(DerivedConvertible convertible)
    {
        System.Console.WriteLine("Called the most derived method");
        return this;
    }

    public DerivedConvertibleConverter Convert(Convertible convertible)
    {
        System.Console.WriteLine("Called the least derived method");
        return this;
    }
}

public abstract class AbstractConvertible {}

public class Convertible : AbstractConvertible {}

public class DerivedConvertible : Convertible {}

从基类中删除派生类型参数时,将调用转换的派生版本.我不希望这种差异,因为我不希望转换的抽象版本的接口发生变化.但是,我一定是错的.谁能解释为什么会出现这种差异?非常感谢你提前.

解决方法

In the sample above,the overload of Convert that does not exist in the abstract parent (and is less derived) is called. I would expect that the most derived version,from the parent class,would be called

很多人都有这种期望.但是,您观察到的行为是正确的,并且是设计的.

过载分辨率算法是这样的.首先,我们列出了您可以调用的所有可访问方法.覆盖虚方法方法被认为是声明它们的类的方法,而不是覆盖它们的类.然后我们过滤掉那些无法将参数转换为形式参数类型的参数.然后我们过滤掉任何类型的方法都比具有适用方法的任何类型都少.然后我们确定哪种方法比另一种更好,如果还剩下多个方法的话.

在您的情况下,有两种可能的适用方法.采用DerivedConvertible的方法被认为是基类的方法,因此不如采用Convertible的方法.

这里的原则是覆盖虚方法是一个可以改变的实现细节,而不是提示编译器选择覆盖方法.

更一般地,过载分辨率算法的这些特征旨在帮助缓解脆性基类问题的各种版本.

有关这些设计决策的更多详细信息,请参阅有关此主题文章

http://blogs.msdn.com/b/ericlippert/archive/2007/09/04/future-breaking-changes-part-three.aspx

When the derived type argument is removed from the base class,the most derived version of Convert is called. I would not expect this difference,since I would not have expected the interface of the abstract version of Convert to have changed

这个问题是基于错误的前提;未调用派生的最多版本.程序片段是错误的,因此不能编译,因此不会调用任何方法;程序没有运行,因为它没有编译.

原文链接:https://www.f2er.com/csharp/243183.html

猜你在找的C#相关文章