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

标签 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; }
}

实际输出:

FOO
FOOBAR
FOO

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

期望的输出:

FOO
FOOBAR
FOOBAR  // because theDerivedObject is an instance of DerivedClass 

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

这在 C# 中可行吗?


编辑:

澄清 - 实际上不会有显式转换,因为项目很可能在混合类型集合的列表中:

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

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

实际输出:

FOO
FOO

期望的输出:

FOO
FOOBAR

显然类型转换仍在发生 - 但要删除它并不容易。

最佳答案

这段代码让我想起了 Haddocks' Eyes诗:

But I was thinking of a plan
 To dye one's whiskers green,
And always use so large a fan
 That they could not be seen.

首先,您的代码创建了一个子类,然后将对象强制转换回基类,因此编译器看不到实际类型!您的示例中的重载在编译时得到解决,因此 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;
    }
}

“魔法”就在这条线上:

return ComposeImpl((dynamic)item);

item 被转换为 dynamic,它告诉系统必须根据运行时选择 ComposeImpl 的实际重载BaseClass 对象的类型。

关于c# - 是否有可能让 c# 使用大多数特定类型而不是基类型的方法重载?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35770767/

相关文章:

C++ 继承和成员函数指针

c++ - 在 C++ 中选择重载模板函数时的优先级

c# - 在删除之前更新实体

c# - 正则表达式从 img 标签获取 src 值

Wcf服务继承(扩展服务)

javascript - 将 @grant 添加到 GM 脚本会破坏 XMLHttpRequest.prototype.open 的过载吗?

java - 重载构造函数调用其他构造函数,但不是第一条语句

c# - vsto : c# change localization of Excel UI objects, 例如功能区,在运行时

c# - TPL Dataflow SingleProducerConstrained 是指源 block 的数量还是它们的并行度?

c++ - 继承和列表