0

假设我有一个重载的方法,例如void PrintInfo(Person)andvoid PrintInfo(Item)等等。我尝试通过传入一个对象来调用这些方法。

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

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

4

3 回答 3

2

All Persons are objects , but not all objects are Persons. Because of this you can pass a Person to a method that accepts an object but you can't pass an object to a method that requires a Person.

It sounds like you have some common bit of functionality between various objects that you want to use. Given this, it would be best to find either a common ancestor that has all of the functionality that you need, or an interface that they all implement (that again provides everything that you need).

In the case of printing, you may just need the ToString method. In that case, you can just have the method accept an object and call ToString on it. (That's what many print methods do, such as Console.WriteLine.

于 2012-07-25T16:06:24.443 回答
1

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

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

有几种方法可以解决这个foo问题 - 类型的制作是一种dynamic- 这将导致在编译时选择正确的重载。这样做的问题是您失去了类型安全性——如果您没有为该类型提供适当的重载,您的应用程序仍将编译,但当您尝试打印不受支持的类型的信息时会崩溃。

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

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

public interface IHasPrintInfo { String PrintInfo { get; } }

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

public void PrintInfo(IPrintInfo info) { 
    Console.WriteLine(info.PrintInfo);
}
于 2012-07-25T16:11:02.123 回答
0

这里它对编译器有歧义;编译器无法确定您打算调用哪个版本的方法(Person/Item)。

于 2012-07-25T16:11:53.043 回答