簡體   English   中英

使用從反射中獲取類型的投射通用對象

[英]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分別使用outin關鍵字實現的。 在 .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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM