是否有可能让c#使用大多数特定类型的方法重载而不是基类型?

Kai*_*ine 4 c# inheritance overloading

如果您有一个使用派生类型重载的方法,则在运行时调用的方法取决于您的变量的类型,即使基础对象实际上是派生类型:

class Program
{
    static void Main(string[] args)
    {
        BaseClass theBaseObject = new BaseClass
        {
            Foo = "FOO"
        };
        DerivedClass theDerivedObject = new DerivedClass
        {
            Foo = "FOO",
            Bar = "BAR"
        };

        Processor processor = new Processor();

        Console.WriteLine(processor.Compose(theBaseObject));
        Console.WriteLine(processor.Compose(theDerivedObject));
        Console.WriteLine(processor.Compose((BaseClass) theDerivedObject));
    }
}

public class Processor
{
    public string Compose(BaseClass item)
    {
        return item.Foo;
    }

    public string Compose(DerivedClass item)
    {
        return Compose((BaseClass)item) + item.Bar;
    }
}

public class BaseClass
{
    public string Foo { get; set; }
}

public class DerivedClass : BaseClass
{
    public string Bar { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

实际产量:

FOO
FOOBAR
FOO
Run Code Online (Sandbox Code Playgroud)

我想找到一种方法来改变这种行为,以便为给定的参数调用最具体的方法.

期望的输出:

FOO
FOOBAR
FOOBAR  // because theDerivedObject is an instance of DerivedClass 
Run Code Online (Sandbox Code Playgroud)

这将允许对一堆项目进行特定处理,所有项目都来自基础.

这可能在c#中吗?


编辑:

澄清 - 在实践中不会有明确的演员表,因为这些项目可能会出现在混合类型集合的列表中:

使用没有显式强制转换的列表的示例:

    foreach (BaseClass item in new []{ theBaseObject, theDerivedObject })
    {
        Console.WriteLine(processor.Compose(item));
    }
Run Code Online (Sandbox Code Playgroud)

实际产量:

FOO
FOO
Run Code Online (Sandbox Code Playgroud)

期望的输出:

FOO
FOOBAR
Run Code Online (Sandbox Code Playgroud)

显然演员阵容仍在发生 - 但要删除它并不容易.

das*_*ght 10

这段代码让我想起了哈多克斯的眼睛诗:

但我正在考虑一个计划
 将一个人的胡须染成绿色,
并且总是使用如此大的粉丝,
 以至于他们无法看到.

首先,您的代码创建了一个子类,但随后它将对象强制转换回基类,因此编译器无法看到实际类型!示例中的重载在编译时解析,因此Compose(BaseClass item)将调用它.

你可以通过隐藏所有重载,并暴露一个采用基类并执行动态转换的方法来扭转局面并让.NET动态地解决过载:

public class Processor {
    public string Compose(BaseClass item) {
        return ComposeImpl((dynamic)item);
    }
    private string ComposeImpl(BaseClass item) {
        return item.Foo;
    }
    private string ComposeImpl(DerivedClass item) {
        return ComposeImpl((BaseClass)item) + item.Bar;
    }
}
Run Code Online (Sandbox Code Playgroud)

"神奇"就在这条线上:

return ComposeImpl((dynamic)item);
Run Code Online (Sandbox Code Playgroud)

item被转换为dynamic,它告诉实际过载系统ComposeImpl基于所述的运行时类型必须被拾取BaseClass对象.

  • 这是一个很好的解决方案,因为它不需要更改参数类(它可以在处理器中完成),当你有很多派生类型时,你不会得到一个很长的列表'如果然后这个'类型逻辑 (2认同)