.net 如何使用 typeof 或 GetType() 作为通用模板?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/302577/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to use typeof or GetType() as Generic's Template?
提问by faulty
If it's harder to explain using words, let's look at an example I have a generic function like this
如果用词更难解释,让我们看一个例子,我有一个像这样的通用函数
void FunctionA<T>() where T : Form, new()
{
}
If I have a reflected type, how do I use it with the above function? I'm looking forward to do this
如果我有一个反射类型,我如何将它与上述功能一起使用?我期待着这样做
Type a = Type.GetType("System.Windows.Forms.Form");
FunctionA<a>();
Of cause the above method doesn't work.
由于上述方法不起作用。
采纳答案by faulty
You can't. Generics in .NET must be resolved at compile time. You're trying to do something that would resolve them at runtime.
你不能。.NET 中的泛型必须在编译时解析。您正在尝试做一些可以在运行时解决它们的事情。
The only thing you can do is to provide an overload for FunctionA that takes a type object.
您唯一能做的就是为 FunctionA 提供一个采用类型对象的重载。
Hmmm... the commenter is right.
嗯……评论者是对的。
class Program
{
static void Main(string[] args)
{
var t = typeof(Foo);
var m = t.GetMethod("Bar");
var hurr = m.MakeGenericMethod(typeof(string));
var foo = new Foo();
hurr.Invoke(foo, new string[]{"lol"});
Console.ReadLine();
}
}
public class Foo
{
public void Bar<T>(T instance)
{
Console.WriteLine("called " + instance);
}
}
回答by devi
class Program
{
static void Main(string[] args)
{
int s = 38;
var t = typeof(Foo);
var m = t.GetMethod("Bar");
var g = m.MakeGenericMethod(s.GetType());
var foo = new Foo();
g.Invoke(foo, null);
Console.ReadLine();
}
}
public class Foo
{
public void Bar<T>()
{
Console.WriteLine(typeof(T).ToString());
}
}
it works dynamicaly and s can be of any type
它动态地工作并且 s 可以是任何类型
回答by Stefan Turcanu
A few years late and from a msdn blog, but this might help:
从 msdn 博客晚了几年,但这可能会有所帮助:
Type t = typeof(Customer);
IList list = (IList)Activator.CreateInstance((typeof(List<>).MakeGenericType(t)));
Console.WriteLine(list.GetType().FullName);
回答by Steve
I solved this problem in a different way. I have a list class that encapsulates the (real) Dapper functionality. It inherits from a base class that is the dummy class for mocking. Every method in the base class is overridden by the real class. Then I don't need to do anything special. If in the future, I want to do something special with SQLiteor a home-grown in-memory database, I can always add that to the base class later if I wish.
我以不同的方式解决了这个问题。我有一个封装了(真正的)Dapper 功能的列表类。它继承自一个基类,该基类是用于模拟的虚拟类。基类中的每个方法都被真正的类覆盖。那么我不需要做任何特别的事情。如果将来我想用自己SQLite的内存数据库做一些特别的事情,如果我愿意,我可以随时将其添加到基类中。

