我有一个抽象基类的一些推广方法的类型参数,让我们说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))
- 为尝试创建Abstract类的实例抛出异常!
我发现的唯一解决方法是呕出来下面的代码使用运行时类型,以获得正确的泛型方法:
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 });
}
为了上帝的爱,还有没有其他的办法吗?硬编码的字符串与类中的方法名称是不可接受的。
我有这样一大堆的扩展方法,其中通用的方法需要推断运行时类型,而不是编译时类型。 Someone告诉我,我可以巧妙地使用dynamic
来解决这个问题。是这样吗?
你找到了我:) – Alain