【发布时间】:2016-06-16 16:42:00
【问题描述】:
如果您有一个使用派生类型重载的方法,则在运行时调用的方法取决于变量的类型,即使底层对象实际上是派生类型:
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
显然演员阵容仍在进行中 - 但要移除它并不容易。
【问题讨论】:
-
当你将它转换为基本类型时,你实际上是在告诉它忽略它自己的任何属性
-
摆脱 (BaseClass) 演员表
-
我认为您可能对双重分派感兴趣,它利用了在运行时选择虚拟成员函数这一事实(而不是通过参数选择函数重载,这是在编译时解决的) ,正如你所展示的)。这个想法是您的
Processor.Compose()方法只是“回调” argument 的虚函数(然后在运行时解析为最派生的实现)。这个乒乓球就是名字中“双”的原因。 -
@JNF 好吧,您是在告诉编译器选择哪个
Compose()。您不会告诉接受强制转换的对象失去 any 属性;它没有改变。 -
@PeterA.Schneider,它可以在其他上下文中使用,但在这里它被视为基本类型。编译器不会以任何方式引用它
标签: c# inheritance overloading