是否可能(最好不使用任何第三方库),创建一个在C#中运行时确定其类型的函数?
e.g
public static void myfunc(var x)
{
System.Windows.Forms.MessageBox.Show(x); //just an example
}
注意:我希望运行时确定参数的类型,并且不希望稍后将参数转换为其他类型,如果我使用泛型则需要。我不想要:
myfunc<T>(T x)
// and then :
MessageBox.Show((string)m);
更新: 我实际上正在为my programming language创建一个函数解析器,它转换为C#代码。在我的语言中,我希望在运行时确定参数类型始终。我正在寻找一些好的C#功能,以便轻松翻译。 例如 用我的语言语法:
function msg << x
MessageBox.Show x
end
需要转换为在编译时不要求类型的东西,但在运行时需要一个类型。 e.g
public static void msg(var x)
{
System.Windows.Forms.MessageBox.Show(x);
}
答案 0 :(得分:10)
C#4中为运行时绑定引入的关键字是dynamic
。
public static void myfunc(dynamic x)
这允许您对在编译时未选中的x进行假设,但如果这些假设无效,则会在运行时失败。
public static void MakeTheDuckQuack(dynamic duck)
{
Console.WriteLine(duck.Quack());
}
这里假设该参数将具有名为Quack
的方法,该方法不接受任何参数并返回一个值,该值可以用作Console.WriteLine
的参数。如果这些假设中的任何一个无效,您将会遇到运行时故障。
给定定义为
的类class Duck
{
public string Quack()
{
return "Quack!";
}
}
class FakeDuck
{
public string Quack()
{
return "Moo!";
}
}
方法调用
MakeTheDuckQuack(new Duck());
MakeTheDuckQuack(new FakeDuck());
MakeTheDuckQuack(42);
前两个成功,因为运行时绑定成功,第三个导致异常,因为System.Int32
没有名为Quack
的方法。
一般来说,如果可能的话,你可能希望避免这种情况,因为你基本上规定一个参数在没有严格定义它的情况下实现某种类型的接口。如果您正在使用互操作方案,那么也许这就是您必须要做的事情。如果您正在使用您控制的类型,那么尝试通过接口和/或基类实现编译时安全性会更好。您甚至可以使用不同的策略(例如适配器模式)来使您无法控制(或不能更改)的类型符合给定的接口。
答案 1 :(得分:2)
如果您需要知道类型......那么您需要知道类型。你也不能吃蛋糕,也不能吃。
首先,您的示例中的强制转换是不必要的,因为所有对象都实现ToString()
。而不是告诉我们您认为您需要什么,告诉我们您要解决的问题。几乎可以肯定通过泛型或使用dynamic
关键字来解决问题(尽管很少需要dynamic
),但我们需要更多信息。如果你添加更多,我会更新这个答案。
答案 2 :(得分:0)
您可以使用某种类型的对象,或者,如果您不知道有多少项可用,则可以使用params对象数组,即params object[] cParams
。