通用构造函数和反射

tan*_*ius 9 c# generics reflection

是否有可能看到哪个构造函数是通用构造函数?

internal class Foo<T>
{
  public Foo( T value ) {}
  public Foo( string value ) {}
}

var constructors = typeof( Foo<string> ).GetConstructors();
Run Code Online (Sandbox Code Playgroud)

属性'ContainsGenericParameters'返回两个构造函数false.有没有办法找出构造函数[0]是通用的?它们都有相同的签名,但我想称之为"真正的"字符串.

编辑:

我想使用调用给定的类型

ilGen.Emit( OpCodes.Newobj, constructorInfo );
Run Code Online (Sandbox Code Playgroud)

所以我需要使用绑定版本.但我想调用"最好的"构造函数.这应该是标准行为.我打电话的时候

new Foo<string>()
Run Code Online (Sandbox Code Playgroud)

调用带有字符串签名的构造函数(而不是具有通用签名的构造函数).我的代码也应该这样.

Col*_*ett 8

您需要System.Reflection.ParameterInfo.ParameterType.IsGenericParameter.这是一个通过的VS2008单元测试,说明了这一点:

类:

public class Foo<T>
{
    public Foo(T val)
    {
        this.Value = val.ToString();
    }
    public Foo(string val)
    {
        this.Value = "--" + val + "--";
    }

    public string Value { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

测试方法:

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);
Run Code Online (Sandbox Code Playgroud)

这里值得注意的是parms [0] .ParameterType.IsGenericParameter检查,它检查参数是否是泛型.

一旦找到了构造函数,就可以将ConstructorInfo传递给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;
}
Run Code Online (Sandbox Code Playgroud)

不完全确定你的意图是什么.

  • 顺便说一句.用工作单元测试来回答这个问题的好风格! (3认同)
  • GetGenericTypeDefinition()正是我错过的.非常感谢你! (2认同)