泛型构造函数和反射 [英] Generic constructors and reflection

查看:58
本文介绍了泛型构造函数和反射的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆