我有一個抽象基類的一些推廣方法的類型參數,讓我們說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