Getting a generic method to infer the type parameter from the runtime type

旧时模样 提交于 2019-12-24 04:19:25

问题


I have some extension methods for an abstract base class, let's say Pet, that themselves call a generic method that takes in that type parameter.

public static Pet_ExtensionMethods
{
    public static T PermuteFromData<T>(this T thisPet, string data) where T : Pet
    {
        T newPet = new SomeDeserializer().Deserialize<T>(data);
        newPet.someProperty = thisPet.someProperty;
        return newPet;
    }
}

This has worked great for me, as I can say things like:

Dog newDog = existingDog.PermuteFromData(dogData);
Cat newCat = existingCat.PermuteFromData(catData);

And all with the same base implementation and no code duplication.

But I recently discovered a disturbing problem! If I go:

Pet myPet = existingDog;
string petData = dogData;
Pet newPet = myPet.PermuteFromData(petData);

I want the behavior to be the same, but now the compiler is electing to run PermuteFromData<Pet> which in turn calls Deserialize<Pet>, which in the bowels of some library I don't control tries to go Activator.CreateInstance(typeof(T)) - which throws an Exception for trying to create an instance of an Abstract class!

The only workaround I've found is to vomit out the following code to get the correct generic method using the run-time type:

public static T PermuteFromDataFix<T>(this T thisPet, string data) where T : Pet
{
    return (T) typeof(Pet_ExtensionMethods).GetMethod("PermuteFromData")
        .MakeGenericMethod(new Type[] { thisPet.GetType() })
        .Invoke(null, new object[] { thisPet, data });
}

For the love of god, is there any other way? Having a hard coded string with the name of a method in a class is just unacceptable.

I have a whole bunch of extension methods like this where the generic method needs to infer the runtime type, not the compile time type. Someone told me I can get around this with a clever use of dynamic. Is that so?


回答1:


You can try using dynamic, but I'm not sure you can do this using extension method syntax.

Try this one first:

Pet_ExtensionMethods.PermuteFromData((dynamic)pet, petData);

It should work as expected. Then you can try

((dynamic)pet).PermuteFromData(petData);

but I'm not sure it will resolve to correct method.



来源:https://stackoverflow.com/questions/20985294/getting-a-generic-method-to-infer-the-type-parameter-from-the-runtime-type

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