简体   繁体   English

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

[英]Cast object into appropriate type for overloaded methods

Say I have a method that is overloaded such as void PrintInfo(Person) and void PrintInfo(Item) , and so on. 说我有一个被重载的方法,例如void PrintInfo(Person)void PrintInfo(Item)等等。 I try to invoke these methods by passing in an Object. 我尝试通过传入一个对象来调用这些方法。

I'm wondering why it is giving me an error when I do this; 我想知道为什么这样做会给我一个错误。 aren't all classes inherited from Object? 不是所有的类都继承自Object吗? I want to avoid doing an if/switch statement where I check which type the Object is before calling the appropriate method. 我想避免在调用适当的方法之前执行if / switch语句来检查对象是哪种类型。

What do you guys think is the best approach in this case? 你们认为这种情况下最好的方法是什么?

All Person s are object s , but not all object s are Person s. 所有的Person都是object ,但并非所有的object都是Person 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 . 因此,您可以将Person传递给接受object的方法,但不能将object传递给需要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. 在打印的情况下,您可能只需要ToString方法。 In that case, you can just have the method accept an object and call ToString on it. 在这种情况下,您只需让该方法接受一个object并对其调用ToString (That's what many print methods do, such as Console.WriteLine . (这就是许多打印方法的功能,例如Console.WriteLine

You need to understand that because C# is a statically typed language (barring dynamic ) the particular overload that is chosen (called overload resolution ) is determined at compile time, not run time. 您需要了解,因为C#是静态类型的语言( dynamic禁止),所以选择的特定重载(称为重载解析 )是在编译时而不是运行时确定的。 That means that the compiler needs to be able to unequivocally determine what type your argument is. 这意味着编译器需要能够明确确定参数是什么类型。 Consider: 考虑:

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

There are a few ways to solve this- making foo of type dynamic is one- that will cause the correct overload to be chosen at compile time. 有几种方法可以解决这一问题-使dynamic类型的foo为单-会导致在编译时选择正确的重载。 The problem with that is that you lose type safety- if you don't have an appropriate overload for that type, your application will still compile but will crash when you try to print the unsupported type's info. 这样做的问题是您失去了类型安全性-如果您没有适当的重载类型,则您的应用程序仍将编译,但是当您尝试打印不受支持的类型信息时会崩溃。

An arguably better approach is to ensure that foo is always of the correct type, rather than just Object . 一种可以说是更好的方法是确保foo始终是正确的类型,而不仅仅是Object

As @Servy suggests, another approach is to attach the behavior to the type itself. 正如@Servy所建议的,另一种方法是将行为附加到类型本身。 You could, for instance, make an interface IHasPrintInfo : 例如,您可以创建一个接口IHasPrintInfo

public interface IHasPrintInfo { String PrintInfo { get; } }

and implement that interface on all items whose info you might print. 并在您可能会打印其信息的所有项目上实现该界面。 Then your PrintInfo function can just take an IPrintInfo: 然后,您的PrintInfo函数就可以使用IPrintInfo:

public void PrintInfo(IPrintInfo info) { 
    Console.WriteLine(info.PrintInfo);
}

here its ambiguate for compiler; 这里对编译器含糊不清; compiler can't figure out which version of method (Person/Item) you are intended to call. 编译器无法确定您打算调用哪个版本的方法(人员/项目)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM