获取通用方法来从运行时类型中推断出类型参数 [英] Getting a generic method to infer the type parameter from the runtime type

查看:79
本文介绍了获取通用方法来从运行时类型中推断出类型参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个抽象基类的扩展方法,比如 Pet ,它们自己调用一个接受该类型参数的泛型方法。

  public static Pet_ExtensionMethods 
{
public static T PermuteFromData< T>(this T thisPet,string data)where T:Pet
{
T newPet = new SomeDeserializer()。反序列化< T>(data);
newPet.someProperty = thisPet.someProperty;
返回newPet;


$ / code $ / pre

这对我来说很好,正如我可以说的例如:

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

而且所有的基本实现都是相同的,并且没有代码重复。

但我最近发现了一个令人不安的问题!如果我去:

  Pet myPet = existingDog; 
字符串petData = dogData;
Pet newPet = myPet.PermuteFromData(petData);

我想要的行为是相同的,但现在编译器正在选择运行 PermuteFromData< Pet> ,然后调用 Deserialize< Pet> ,这在我不控制的某些库的肠子里试图去 Activator.CreateInstance(typeof(T)) - 它为抛出一个Abstract类的实例抛出Exception!



我找到的唯一解决方法是吐出以下代码以使用运行时类型获得正确的泛型方法:

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

对于上帝的爱,有没有其他办法?在一个类中有一个硬编码的字符串和一个方法的名字是不可接受的。



我有一大堆像这样的扩展方法,其中泛型方法需要推断运行时类型,而不是编译时类型。 有人告诉我,我可以巧妙地使用 dynamic 。是这样吗?

解决方案

您可以尝试使用 dynamic '你不能确定你可以使用扩展方法的语法来做到这一点。



首先试试这个:

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

它应该按预期工作。然后你可以尝试

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

但我不确定它会解决方法。


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?

解决方案

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.

这篇关于获取通用方法来从运行时类型中推断出类型参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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