假设我有一个重载的方法,例如void PrintInfo(Person)
和void PrintInfo(Item)
,依此类推。我尝试通过传入一个Object来调用这些方法。
我想知道为什么我这样做会给我一个错误;是不是所有继承自Object的类?我想避免做一个if / switch语句,在调用适当的方法之前我检查Object的类型。
在这种情况下,你们认为最好的方法是什么?
答案 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)的版本。