如何将动态用作泛型

本文关键字:泛型 动态 | 更新日期: 2023-09-27 18:31:01

如何使用动态作为泛型?

var x = something not strongly typed;
callFunction<x>();

而这个

dynamic x = something not strongly typed;
callFunction<x>();

两者都会产生此错误

Error   1   The type or namespace name 'x' 
could not be found (are you missing a using directive or an assembly reference?)

我该怎么做才能x使其足够合法,可以在<x>中使用?

如何将动态用作泛型

您可以使用类型推断来排序调用:

dynamic x = something not strongly typed;
CallFunctionWithInference(x);
...
static void CallFunctionWithInference<T>(T ignored)
{
    CallFunction<T>();
}
static void CallFunction<T>()
{
    // This is the method we really wanted to call
}

这将根据 x 值的执行时类型在执行时确定类型参数,使用与x将其作为编译时类型时使用的类型推断相同。该参数仅用于使类型推断工作。

请注意,与 Darin不同,我相信这是一种有用的技术 - 在完全相同的情况下,前动态你最终会调用带有反射的通用方法。您可以使这一部分代码动态化,但保持代码的其余部分(从泛型类型向下)类型安全。它允许一个步骤是动态的 - 只是您不知道类型的单个位。

很难说你到底想做什么。但是,如果要使用与某个对象相同的类型参数调用泛型方法,则不能直接执行此操作。但是你可以编写另一个将你的对象作为参数的方法,让dynamic推断类型,然后调用你想要的方法:

void HelperMethod<T>(T obj)
{
    CallFunction<T>();
}
…
dynamic x = …;
HelperMethod(x);

你不能。泛型的全部意义在于编译时安全性,这意味着它们必须在编译时知道。动态的全部意义在于,您不需要在编译时知道确切的类型并使用运行时调度=>这与泛型完全相反。所以不要浪费你的时间=>一旦你得到了动态/反射路径,你就可以忘记泛型和编译时的安全性。你将不得不走这条路直到最后。

所以回答你的问题:

我可以对 x 做什么才能使其足够合法,可以在 中使用?

您唯一能做的是使用编译时已知的类型,否则无法使用泛型。

您收到该错误是因为x不是一个类型。您需要将类型指定为类型参数。

实际上,如果正确使用dynamic,则可以将其用作类型参数:

var dict = new Dictionary<string, dynamic>();
dict.Add("Item1", 123);
dict.Add("Item2", "Blah");

这可以很好地编译和运行。

完成此操作的最快方法是使匿名类型成为真实类型。

所以而不是

var x = new { Value = "somevalue", Text = "sometext" };

你需要做的

class MyClass
{
    string Text, Value;
}
....
var x = new MyClass() { Value = "somevalue", Text = "sometext" };
//this should work now
callFunction<MyClass>(x);

你应该能够像这样调用函数

callFunction<dynamic>();

如果您的函数定义为

public void callFunction<T>(T arg) {
    ...
}

您可以简单地调用它

callFunction(x);

在许多情况下,C# 能够推断泛型类型参数。