C# Generic method and dynamic type problem [duplicate]

这一生的挚爱 提交于 2019-12-17 19:29:18

问题


I have a generic method declared as follow :

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

So, generally to use it I simply need to do say :

myObject.Duplicate<int>()

But here, what I'd like to do is pass the type by a variable, but it doesn't work, here is how I try to do this :

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

If someone can help me ?

Thank in advance.


回答1:


You have to use reflection, basically:

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



回答2:


Where you have the type as a variable you don't really have a good candidate for generic methods, especially as your method returns nothing.

You would be better off with:

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

Then your code becomes:

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

You can use Jon Skeet's (correct) answer to call your method by reflection, but I can't see what you gain by this method being generic.

The purpose of generics is to preserve the type - so that you don't have to box/unbox value types and so on.

However your duplicate method has no return (it's a void) and no input parameters. Essentially the only input is the type-parameter. This means that somewhere inside your generic method you're probably doing something like:

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

In that case you're not gaining anything by EntityType being a generic type-parameter rather than a regular input parameter, and you're adding the need for awkward and slow reflection when you don't know the input at compile time.




回答3:


You could use a standard method taking a Type as an argument:

myobject.Duplicate(myType);

or you can try with reflection, something like:

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



回答4:


It's not quite clear of the exact function of Duplicate(), but the following example works when your type you want to pass in to Duplicate() is a class or an int.

Essentially, don't pass in a type, pass in an example object. This test method illustrates the call (two tests in one method)

    [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);
    }

The Duplicate() method has a type parameter linked to the example object, but does not need to be called with the type given as a parameter, it infers it from the example object.

Here is the class with a Duplicate() method:

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;
    }
}

To complete the picture, this is the AnotherObject class.

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

This code may have some problems inside the Duplicate() method when the type passed in is a value type like int. It depends on what you want Duplicate() to do with the int (you may have to be pass it in as a nullable int).

It works well for reference types (classes).



来源:https://stackoverflow.com/questions/5961816/c-sharp-generic-method-and-dynamic-type-problem

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!