【发布时间】:2021-12-28 17:17:18
【问题描述】:
我有一个非泛型 IList,我想在运行时根据 enum 值进行转换。
我无法在实现中更改非泛型 IList 的类型,因为它是库代码。
我也不想使用反射(因为它很慢)或动态关键字(因为它不安全并且可能导致错误)。
在图书馆代码中有以下类:
public class ListView //THIS IS LIBRARY CODE AND CAN NOT BE CHANGED
{
public IList itemsSource { get; set; }
}
然后在继承自 ListView 的 CustomListView 类中,我想根据 ItemType 将 itemsSource 转换为适当的类。
另一个限制是 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");
}
}
我将如何实现它?
编辑/附加
正如你们指出的,我应该澄清一些事情。
A 类和 B 类确实具有相同的基类。 但是我希望能够不再从基本类型中转换它(因为我已经在 GetItems() 方法中转换它并且 ItemType 的值也是已知的)。
我希望能够做到以下几点
IList<A> aItems = listView.GetItems()
没有强制转换。
所有这一切背后的想法是拥有一个可以处理多种项目类型的通用 CustomListView。这些项目将被添加到 itemSource。这些项目的类型由 ItemType 确定。
我就是这样用的
public class UiForClassA
{
public void Foo()
{
CustomListView customListView = new CustomListView(ItemType.A);
IList<A> itemsOfCustomListView = customListView.GetItems(); //No cast needed because it should somehow implicitly know that.
}
}
我不想在使用 CustomListView 的任何地方都使用 Casts。它应该以某种方式隐式返回正确的项目。
为了您的信息,我使用 Unity UI Toolkit Framework,但这与问题并不真正相关。
【问题讨论】:
-
如果类“A”和“B”没有通用功能,那么您应该返回“IList
-
你不能这样做。指定类型参数的是调用者。您必须声明
public IList<T> GetItems<T>()并使用var list = GetItems<A>();调用它。如果GetItems返回不同类型的列表,你想如何消费它们?消费者也需要是通用的。
标签: c# generics dynamic reflection runtime