将对象转换为适当的类型以用于重载方法

时间:2012-07-25 16:04:06

标签: c# casting polymorphism

假设我有一个重载的方法,例如void PrintInfo(Person)void PrintInfo(Item),依此类推。我尝试通过传入一个Object来调用这些方法。

我想知道为什么我这样做会给我一个错误;是不是所有继承自Object的类?我想避免做一个if / switch语句,在调用适当的方法之前我检查Object的类型。

在这种情况下,你们认为最好的方法是什么?

3 个答案:

答案 0 :(得分:2)

所有Person都是object,但并非所有object都是Person。因此,您可以将Person传递给接受object的方法,但无法将object传递给需要Person的方法。

听起来你想要使用的各种对象之间有一些共同的功能。鉴于此,最好找到一个具有所需功能的共同祖先,或者它们都实现的接口(再次提供您需要的所有功能)。

在打印的情况下,您可能只需要ToString方法。在这种情况下,您可以让方法接受object并在其上调用ToString。 (这就是许多印刷方法所做的,例如Console.WriteLine

答案 1 :(得分:1)

您需要了解,因为C#是一种静态类型语言(禁止dynamic)所选择的特定重载(称为重载决策)是在编译时确定的,而不是运行时。这意味着编译器需要能够明确地确定您的参数是什么类型。考虑:

Object foo;
foo = "String";
foo = 5;
PrintInfo(foo); // Which overload of printinfo should be called?  The compiler doesn't know!

有几种方法可以解决这个问题 - 使类型foo的{​​{1}}为1 - 这将导致在编译时选择正确的重载。问题在于您丢失了类型安全性 - 如果您没有适合该类型的重载,您的应用程序仍将编译,但在您尝试打印不受支持的类型信息时会崩溃。

可以说更好的方法是确保dynamic始终是正确的类型,而不仅仅是foo

正如@Servy建议的那样,另一种方法是将行为附加到类型本身。例如,您可以创建一个接口Object

IHasPrintInfo

并在可能打印其信息的所有项目上实现该接口。然后你的PrintInfo函数可以采用IPrintInfo:

public interface IHasPrintInfo { String PrintInfo { get; } }

答案 2 :(得分:0)

这里有编译器的模糊;编译器无法确定要调用的方法(Person / Item)的版本。