![](/img/trans.png)
[英]How to implement a dynamic generic type return method without casting at runtime in C#?
[英]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.