Dav*_*bbo 4 c# generics dynamic
请考虑以下代码:
class Program {
void Foo<T>() { }
static void Main(string[] args) {
dynamic p = new Program();
p.Foo();
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,对p.Foo()的调用无效,因为动态绑定器无法知道要用于T的类型.具体的失败是:
" 无法从用法中推断出方法'ConsoleApplication1.Program.Foo()'的类型参数.请尝试明确指定类型参数. "
现在我的问题是:有没有办法指定泛型类型,或者这种方法是不是可以使用'dynamic'来调用?
Jon*_*eet 14
正如Jared所说,您可以像在静态调用中一样在代码中指定它:
using System;
class Program {
void Foo<T>() {
Console.WriteLine(typeof(T));
}
static void Main(string[] args) {
dynamic p = new Program();
p.Foo<string>();
}
}
Run Code Online (Sandbox Code Playgroud)
上面的代码打印出来System.String.
现在,如果你只是T在执行时知道,那就稍微困难了.如果你有一个实例,你可以一起使用动态类型和类型推断:
using System;
class Program {
void Foo<T>() {
Console.WriteLine(typeof(T));
}
static void Main(string[] args) {
dynamic p = new Program();
dynamic v = GetRandomInstance();
// Now to call p.Foo<T> where T is the type of v's value...
Dummy(v, p);
}
static void Dummy<T>(T t, Program p) {
p.Foo<T>();
}
static object GetRandomInstance() {
return DateTime.Now.Hour > 10 ? "hello" : (object) 10;
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:帕维尔在评论中提出了一个惊人的想法.您不需要提供一个实例T,只需一个数组.这意味着您甚至可以使用通常无法获取实例的类型参数T(例如,由于私有构造函数):
using System;
class PrivateConstructor {
private PrivateConstructor() {}
}
class Program {
static void Foo<T>() {
Console.WriteLine(typeof(T));
}
static void CallFooProxy<T>(T[] array) {
Foo<T>();
}
static void CallFoo(Type t) {
dynamic array = Array.CreateInstance(t, 0);
CallFooProxy(array);
}
static void Main(string[] args) {
CallFoo(typeof(PrivateConstructor));
}
}
Run Code Online (Sandbox Code Playgroud)
在有人要求之前 - 不,这不会让你Foo<Enumerable>动态调用- 你仍然不能使用静态类作为类型参数,即使你试图将尝试延迟到执行时间:)
如果由于某种原因所有这些都失败了,它会恢复正常的反射...获取方法信息,调用MakeGenericMethod并调用它.