如何将动态用作通用?

时间:2012-04-12 22:24:24

标签: c# generics dynamic

如何将动态作为通用使用?

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>中使用?

6 个答案:

答案 0 :(得分:16)

您可以使用类型推断对蹦床进行排序:

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将其作为其<时使用的相同类型的推断em>编译时类型。该参数仅 存在以进行类型推断工作。

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

答案 1 :(得分:4)

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

void HelperMethod<T>(T obj)
{
    CallFunction<T>();
}

…

dynamic x = …;
HelperMethod(x);

答案 2 :(得分:2)

你做不到。泛型的全部内容是编译时安全性,这意味着必须在编译时知道它们。动态的全部要点是你不需要在编译时知道确切的类型并使用runtime dispatching =&gt;它与泛型完全相反。所以不要浪费你的时间=&gt;一旦获得动态/反射路径,就可以忘记泛型和编译时的安全性。你必须走这条路直到最后。

所以回答你的问题:

  

我可以对x做些什么才能使其合法使用?

你唯一能做的就是使用在编译时已知的类型,否则就不能使用泛型。

答案 3 :(得分:1)

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

事实上,如果你正确使用它,可以使用dynamic作为类型参数:

var dict = new Dictionary<string, dynamic>();

dict.Add("Item1", 123);
dict.Add("Item2", "Blah");

这编译并运行得很好。

答案 4 :(得分:0)

使这项工作最快捷的方法是让您的匿名类型成为真正的类型。

所以而不是

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);

答案 5 :(得分:0)

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

callFunction<dynamic>();

如果您的功能定义为

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

您只需使用

进行调用即可
callFunction(x);

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