C#通用方法和动态类型问题

时间:2011-05-11 09:11:04

标签: c# generics parameters types

我有一个声明如下的泛型方法:

public void Duplicate<EntityType>() { ... }

所以,通常使用它我只需要说:

myObject.Duplicate<int>()

但是在这里,我想要做的是通过变量传递类型,但它不起作用,这是我尝试这样做的方式:

Type myType = anObject.GetType();
myObject.Duplicate<myType>();

如果有人可以帮助我?

提前感谢。

4 个答案:

答案 0 :(得分:12)

你必须使用反射,基本上:

MethodInfo method = typeof(...).GetMethod("Duplicate");
MethodInfo generic = method.MakeGenericMethod(myType);
generic.Invoke(myObject, null);

答案 1 :(得分:4)

如果您将类型作为变量,那么您通常不具备通用方法的良好候选者,尤其是因为您的方法不返回任何内容。

你会更好:

public void Duplicate(Type entityType) { ... }

然后您的代码变为:

Type myType = anObject.GetType();
myObject.Duplicate(myType);

您可以使用Jon Skeet的(正确的)答案通过反射调用您的方法,但我看不出您通过此方法获得的通用。

泛型的目的是保留类型 - 这样您就不必使用box / unbox值类型等。

但是,您的重复方法没有返回(它是void)且没有输入参数。基本上唯一的输入是type-parameter。这意味着你的泛型方法中的某个地方你可能正在做类似的事情:

public void Duplicate<EntityType>() 
{
 ...
 Type inputType = typeof(EntityType); 
 ...
}

在这种情况下,你不是通过EntityType作为泛型类型参数而不是常规输入参数获得任何东西,并且当你不知道时,你需要增加笨拙和慢速反射的需要在编译时输入。

答案 2 :(得分:0)

您可以使用以Type作为参数的标准方法:

myobject.Duplicate(myType);

或者您可以尝试使用反射,例如:

System.Reflection.MethodInfo mi = typeof(TypeOfMyObject).GetMethod("Duplicate<>");
MethodInfo constructedMethodInfo = mi.MakeGenericMethod(new type[] {myType});
constructedMethodInfo.Invoke(myObject, new object[] {});

答案 3 :(得分:0)

目前还不十分清楚Duplicate()的确切功能,但下面的示例适用于您要传递给Duplicate()的类型是类或int。

基本上,不传入类型,传入示例对象。此测试方法说明了调用(一种方法中的两个测试)

    [TestMethod]
    public void TestMethod1()
    {
        var myObject = new AnObject { AString = "someString" };

        var myOtherObject = new AnotherObject();
        var newObject = myObject.Duplicate(myOtherObject);
        Assert.IsTrue(newObject.AString=="someString");

        var newObject2 = myObject.Duplicate(1);
        Assert.IsTrue(newObject2 is Int32);
    }

Duplicate()方法有一个链接到示例对象的类型参数,但不需要使用作为参数给定的类型进行调用,它会从示例对象中推断出它。

以下是具有Duplicate()方法的类:

public class AnObject
{
    public string AString { get; set; }

    public T Duplicate<T>(T exampleObject)
        where T: new()
    {
        var newInstance = (T)Activator.CreateInstance<T>();

        // do some stuff here to newInstance based on this AnObject
        if (typeof (T) == typeof (AnotherObject))
        {
            var another = newInstance as AnotherObject;
            if(another!=null)
                another.AString = this.AString;
        }

        return newInstance;
    }
}

要完成图片,这是AnotherObject类。

public class AnotherObject
{
    public string AString { get; set; }
}

当传入的类型是 int 之类的值类型时,此代码在Duplicate()方法中可能会出现一些问题。这取决于你想要Duplicate()与int做什么(你可能必须将它作为一个可以为空的int传递)。

适用于引用类型(类)。