簡體   English   中英

在泛型方法中返回特定類型,具體取決於運行時沒有反射或動態的枚舉值

[英]Return specific type in generic method depending on enum value without Reflection or dynamic during runtime

我有一個非泛型IList ,我想在運行時根據enum值進行轉換。

我無法在實現中更改非泛型 IList 的類型,因為它是庫代碼。

我也不想使用反射(因為它很慢)或動態關鍵字(因為它不安全並且可能導致錯誤)。

在庫代碼中有以下 class:

public class ListView //THIS IS LIBRARY CODE AND CAN NOT BE CHANGED
{
  public IList itemsSource { get; set; }
}

然后在繼承自 ListView 的 CustomListView class 中,我想根據 ItemType 將 itemsSource 轉換為適當的 class。

另一個限制是 CustomListView 不能是通用的(由我們使用的庫決定)

public class CustomListView : ListView
{
    public dynamic GetItems()
    {
        switch (ItemType)
        {
            case ItemType.A:
              return itemsSource.Cast<A>().ToList();
            case ItemType.B:
              return itemsSource.Cast<B>().ToList();
            default:
              throw new InvalidOperationException("Not supported");
        }
    }
}

但我希望它直接返回正確的類型,而不是使用動態。

類似的東西(下面的代碼不起作用:):

public IList<T> GetItems(ItemType itemType) //The type of T should change depending on what i return
{
    switch (ItemType)
    {
        case ItemType.A:
          return itemsSource.Cast<A>().ToList();
        case ItemType.B:
          return itemsSource.Cast<B>().ToList();
        default:
          throw new InvalidOperationException("Not supported");
    }
}

我將如何實施?

編輯/附加

正如你們指出的,我應該澄清一些事情。

Class A 和 B 確實具有相同的基礎 class。 但我希望能夠不再從基本類型中轉換它(因為我已經在 GetItems() 方法中轉換它並且 ItemType 的值也是已知的)。

我希望能夠做到以下幾點

IList<A> aItems = listView.GetItems()

無需鑄造。

想想如何使用這個方法:

ItemType itemType = ...;
var x = listView.GetItems(itemType);

itemType的值可以是A ,也可以是B 那么x的類型應該是什么? 它是IList<A>IList<B> ,表達這一點的唯一方法是使用IList<A>IList<B>都繼承自的類型,這將我們帶回到IList 如果您在編譯時不知道您想要的類型,那么嘗試將返回類型更改為更具體的東西沒有多大意義,因為您將無法在沒有反射的情況下訪問它作為更具體的類型。

如果您在編譯時確實知道所需的類型,則提供返回所需類型的方法的重載:

public IList<A> GetAItems() { ... }
public IList<B> GetBItems() { ... }

您希望如何使用這種方法? 類型參數由方法的調用者設置。 無法從方法中設置類型參數。 請說明用途。

你可以試試這些:

IList<T> GetItems<T>(ItemType itemType)
{
    switch (itemType)
    {
        case ItemType.A:
          return (IList<T>)(IList)(itemsSource.Cast<A>().ToList());
        case ItemType.B:
          return (IList<T>)(IList)(itemsSource.Cast<B>().ToList());
        default:
          throw new InvalidOperationException("Not supported");
    }
}
IList GetItems(ItemType itemType)
{
    switch (itemType)
    {
        case ItemType.A:
          return itemsSource.Cast<A>().ToList();
        case ItemType.B:
          return itemsSource.Cast<B>().ToList();
        default:
          throw new InvalidOperationException("Not supported");
    }
}

或者,正如@Qwertyluk 在評論中所建議的那樣,如下所示:

private IList<object> GetItems(ItemType itemType)
{
    
    switch (itemType)
    {
        case ItemType.A:
        case ItemType.B:
          return itemsSource.Cast<object>().ToList();
        default:
          throw new InvalidOperationException("Not supported");
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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