![](/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.