获取从运行时类型推断类型参数的泛型方法



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

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

这对我来说效果很好,因为我可以这样说:

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

并且所有这些都具有相同的基本实现,并且没有代码重复。

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

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

我希望行为相同,但现在编译器选择运行PermuteFromData<Pet>,这反过来又调用Deserialize<Pet>,在我无法控制的某些库的内部尝试Activator.CreateInstance(typeof(T))- 这引发了一个异常,试图创建一个抽象类的实例!

我发现的唯一解决方法是吐出以下代码,以使用运行时类型获取正确的泛型方法:

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

为了神的爱,还有别的办法吗?在类中使用具有方法名称的硬编码字符串是不可接受的。

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

您可以尝试使用dynamic,但我不确定您可以使用扩展方法语法来做到这一点。

先试试这个:

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

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

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

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

最新更新