泛型构造函数和反射 [英] Generic constructors and reflection
问题描述
有可能看到哪个构造函数是通用的吗?
Is it possible to see which constructor was the generic one?
internal class Foo<T>
{
public Foo( T value ) {}
public Foo( string value ) {}
}
var constructors = typeof( Foo<string> ).GetConstructors();
属性'ContainsGenericParameters'返回两个构造函数均为false的信息.有没有办法发现constructors [0]是通用的?它们都具有相同的签名,但是我想将真实"字符串称为一个.
The property 'ContainsGenericParameters' returns me for both constructors false. Is there any way to find out that constructors[0] is the generic one? They both have the same signature, but I would like to call the "real" string one.
我想使用
ilGen.Emit( OpCodes.Newobj, constructorInfo );
所以我需要使用绑定版本.但我想调用最佳"构造函数.那应该是标准行为.当我打电话
so I need to work with the bound version. But I would like to invoke the "best" constructor. That should be the standard behaviour. When I call
new Foo<string>()
具有字符串签名的构造函数(而不是具有通用签名的构造函数)被调用.我的代码也应该如此.
the constructor with the string-signature (and not the one with the generic signature) is called. The same should happen with my code.
推荐答案
您需要System.Reflection.ParameterInfo.ParameterType.IsGenericParameter.这是通过的VS2008单元测试,它说明了这一点:
You want System.Reflection.ParameterInfo.ParameterType.IsGenericParameter. Here's a VS2008 unit test that passes that illustrates this:
班级:
public class Foo<T>
{
public Foo(T val)
{
this.Value = val.ToString();
}
public Foo(string val)
{
this.Value = "--" + val + "--";
}
public string Value { get; set; }
}
测试方法:
Foo<string> f = new Foo<string>("hello");
Assert.AreEqual("--hello--", f.Value);
Foo<int> g = new Foo<int>(10);
Assert.AreEqual("10", g.Value);
Type t = typeof(Foo<string>);
t = t.GetGenericTypeDefinition();
Assert.AreEqual(2, t.GetConstructors().Length);
System.Reflection.ConstructorInfo c = t.GetConstructors()[0];
System.Reflection.ParameterInfo[] parms = c.GetParameters();
Assert.AreEqual(1, parms.Length);
Assert.IsTrue(parms[0].ParameterType.IsGenericParameter);
c = t.GetConstructors()[1];
parms = c.GetParameters();
Assert.AreEqual(1, parms.Length);
Assert.IsFalse(parms[0].ParameterType.IsGenericParameter);
这里值得注意的是parms [0] .ParameterType.IsGenericParameter检查,它检查参数是否为通用.
The notable point here is the parms[0].ParameterType.IsGenericParameter check which checks if the parameter is a generic or not.
一旦找到了构造函数,就可以将ConstructorInfo传递给Emit.
Once you've found your constructor then you've got the ConstructorInfo to pass to Emit.
public System.Reflection.ConstructorInfo FindStringConstructor(Type t)
{
Type t2 = t.GetGenericTypeDefinition();
System.Reflection.ConstructorInfo[] cs = t2.GetConstructors();
for (int i = 0; i < cs.Length; i++)
{
if (cs[i].GetParameters()[0].ParameterType == typeof(string))
{
return t.GetConstructors()[i];
}
}
return null;
}
不确定自己的意图是什么.
Not exactly sure what your intention is though.
这篇关于泛型构造函数和反射的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!