Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将对象强制转换为重载方法的适当类型_C#_Casting_Polymorphism - Fatal编程技术网

C# 将对象强制转换为重载方法的适当类型

C# 将对象强制转换为重载方法的适当类型,c#,casting,polymorphism,C#,Casting,Polymorphism,假设我有一个重载的方法,比如void PrintInfo(Person)和void PrintInfo(Item),等等。我试图通过传入一个对象来调用这些方法 我想知道为什么我这么做的时候它会给我一个错误;不是所有类都从对象继承吗?我希望避免执行if/switch语句,在调用适当的方法之前检查对象的类型 你们认为在这种情况下最好的方法是什么?所有人s都是对象s,但并非所有对象s都是人s。因此,您可以将人传递给接受对象的方法,但不能将对象传递给需要人的方法 听起来,您想要使用的各种对象之间有一些共

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

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


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

所有
s都是
对象
s,但并非所有
对象
s都是
s。因此,您可以将
传递给接受
对象
的方法,但不能将
对象
传递给需要
的方法

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


在打印的情况下,您可能只需要使用
ToString
方法。在这种情况下,您可以让该方法接受一个
对象
,并对其调用
ToString
。(这是许多打印方法所做的,例如
控制台。WriteLine

所有
s都是
对象
s,但并非所有
对象
s都是
s。因此,您可以将
传递给接受
对象
的方法,但不能将
对象
传递给接受
对象的方法。)at需要一名
人员

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


在打印的情况下,您可能只需要
ToString
方法。在这种情况下,您可以让该方法接受
对象
,并在其上调用
ToString
。(这是许多打印方法所做的,例如
控制台。WriteLine

,您需要理解这一点,因为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所建议的,另一种方法是将行为附加到类型本身

public interface IHasPrintInfo { String PrintInfo { get; } }
并在可能打印其信息的所有项目上实现该接口。然后,PrintInfo函数只需获取IPrintInfo:

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

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

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所建议的,另一种方法是将行为附加到类型本身

public interface IHasPrintInfo { String PrintInfo { get; } }
并在可能打印其信息的所有项目上实现该接口。然后,PrintInfo函数只需获取IPrintInfo:

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

这里是编译器的模糊语言;编译器无法确定要调用的方法(个人/项目)的版本。

这里是编译器的模糊语言;编译器无法确定方法(个人/项目)的版本您打算呼叫。

您正在查找
动态
或访问者模式。您正在查找
动态
或访问者模式。