如何将动态作为通用使用?
此
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>
中使用?
答案 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#能够在很多情况下推断泛型类型参数。