C#如何不使用反射和dynamic根据枚举值返回泛型方法对应类型
问题根因
你之前写的泛型方法无法运行的核心原因是:泛型参数T是编译期确定的,无法根据运行时的ItemType枚举值动态变化,所以不同分支返回的IList<A>、IList<B>无法直接兼容IList<T>的返回值声明。
下面提供两个完全符合你所有限制的可行方案:
方案1:泛型方法实现(灵活性更高)
直接在CustomListView中实现无枚举参数的泛型GetItems方法,内部校验类型匹配后返回对应结果:
public class CustomListView : ListView { public ItemType ItemType { get; set; } public CustomListView(ItemType itemType) { ItemType = itemType; } public IList<T> GetItems<T>() { if (typeof(T) == typeof(A) && ItemType == ItemType.A) { return itemsSource.Cast<A>().ToList() as IList<T>; } if (typeof(T) == typeof(B) && ItemType == ItemType.B) { return itemsSource.Cast<B>().ToList() as IList<T>; } throw new InvalidOperationException($"不支持的类型匹配:当前ItemType为{ItemType},请求的返回类型为{typeof(T).Name}"); } }
调用方式:
CustomListView customListView = new CustomListView(ItemType.A); IList<A> itemsOfCustomListView = customListView.GetItems<A>();
该方案优势:后续新增条目类型只需要新增一个if分支即可,不需要新增方法。
注:这里用到的typeof属于编译期类型获取,不属于运行时反射操作,性能无额外损耗,符合要求。
方案2:类型专属方法(调用更简洁)
如果不想在调用时写泛型参数,可以为每个条目类型实现单独的获取方法:
public class CustomListView : ListView { public ItemType ItemType { get; set; } public CustomListView(ItemType itemType) { ItemType = itemType; } public IList<A> GetAItems() { if (ItemType != ItemType.A) { throw new InvalidOperationException($"当前ItemType为{ItemType},无法返回A类型集合"); } return itemsSource.Cast<A>().ToList(); } public IList<B> GetBItems() { if (ItemType != ItemType.B) { throw new InvalidOperationException($"当前ItemType为{ItemType},无法返回B类型集合"); } return itemsSource.Cast<B>().ToList(); } }
调用方式完全符合你的预期,不需要额外强转也不需要写泛型参数:
CustomListView customListView = new CustomListView(ItemType.A); IList<A> itemsOfCustomListView = customListView.GetAItems();
该方案优势:调用更简洁,编译期就能明确知道调用的方法对应什么类型,不会出现类型匹配错误。
内容的提问来源于stack exchange,提问作者EternalColor
相关产品推荐
相关产品推荐

