[英]Cast Generic Object with getting type from Reflection
我正在嘗試在需要動態更改類型的通用對象中投射一個對象。
Dog<T>
繼承Animal
,類“ T
”必須繼承自EntityBase
。 例如, Chihuahua
繼承了EntityBase
。
for (int i = 0; i < list.Count(); i++) {
if (list?.ElementAt(i)?.GetType().GetTypeInfo().BaseType == typeof(Animal))
{
var type = list.ElementAt(i).GetType();
// is wrong, must use a class no a type
// var animal = list.ElementAt(i) as GenericObject<Dog<type>>
// Correct syntax but cast results null
var animal = list.ElementAt(i) as GenericObject<Dog<EntityBase>>
// animal is null
DoStuff(animal);
}
如果我使用此代碼,它會起作用:
if (list?.ElementAt(i)?.GetType() == typeof(Dog<Chihuahua>))
{
DoStuff(list.ElementAt(i) as Dog<Chihuahua>);
}
我想盡可能地通用,非常感謝!
完成后我會分享我正在做的項目!
讓單個列表包含不同類型的相關類型的能力稱為協方差(逆變也是相關的)。 這是在 .NET in
分別使用out
和in
關鍵字實現的。 在 .NET 4.5 中,協方差內置於IEnumerable<T>
。 IEnumerable<T>
由IList<T>
實現,后者由List<T>
。
如果你有一個清單Animal
S,你可以任意添加亞型Animal
到列表中。 然而,當你把那個動物取出來時,在代碼中,你會得到一個Animal
類型的變量,它指向你的Animal
子類型。 所以看起來你只有一個Animal
但它實際上是子類型。 您可以嘗試按照您的建議手動投射所有內容。
還有另一種解決方法 (.NET 4.5),您可以使用dynamic
關鍵字在運行時確定類型。 然后重載DoStuff
方法,它應該按照你想要的方式運行。
public class Animal
{
public string Name;
public Animal() { Name = "Animal"; }
}
public class Dog:Animal
{
public Dog() { Name = "Dog"; }
}
[TestMethod]
public void Test()
{
var list = new List<Animal>();
list.Add(new Dog());
list.Add(new Animal());
foreach(dynamic a in list)
{
DoStuff(a);
}
}
public void DoStuff(Animal animal)
{
Console.WriteLine("{0} is wild", animal.Name);
}
public void DoStuff(Dog dog)
{
Console.WriteLine("{0} is not wild", dog.Name);
}
這是輸出
Test Name: Test
Test Outcome: Passed
Result StandardOutput:
Dog is not wild
Animal is wild
協變和逆變是一個復雜的話題。 查看這些其他帖子。 協方差和逆變之間的區別協方差和向上轉換之間的區別
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.