如何根据集合的参数返回相应类型的集合

  • 本文关键字:集合 类型 返回 参数 何根 c#
  • 更新时间 :
  • 英文 :


我有一个扩展,将枚举的值作为参数,并返回其Select结果的集合。

public static object Filter(this List<Base> bases, FilterType type)
{
switch(type)
{
case FilterType.Alignment:
return bases.Select(x => x.Alignment).ToList();
case FilterType.Faction: 
return bases.Select(x => x.Faction).ToList();   
case FilterType.HP:
return bases.Select(x => x.HP).ToList();  
...
default:
return null;
}
}

并且AlignmentFaction各自是枚举。

public enum AlignmentType {ChaoticEvil, LawfulGood, etc.}
public enum FactionType {Human, Undead, etc.}

因此,返回类型将分别为List<AlignmentType>List<FactionType>List<int>

因此,最终返回类型不可避免地必须是object

但我很快发现,我无法将其投射回其原始类型(例如List<FactionType>(,因为";我不知道它是什么类型的"!

我也不能使用泛型类型,因为结果取决于";值";的参数。

由于同样的原因,我不能使用多态性。

所以有人请好心告诉我我有什么解决方案?

非常感谢!

我觉得您的问题归根结底在于代码的体系结构。";"干净";方法是拥有一个通用接口,所有不同的返回类型都将实现该接口并返回该接口的列表。如果你没有一个共同的类型,你将永远陷入这个问题。否则,您可以将其拆分为3个方法,或者返回一个对象,该对象包含返回值和一个指示值取消类型的标志,但最后一个选项应该是最后的选择。

对于您的具体情况,我认为最好的方法是将该方法分为三种,如下所示:

public static List<AlignmentType> FilterAlignment(this List<Base> bases)
{
return bases.Select(x => x.Alignment).ToList();
}
public static List<FactionType> FilterFaction(this List<Base> bases)
{
return bases.Select(x => x.Faction).ToList();
}
public static List<int> FilterHP(this List<Base> bases)
{
return bases.Select(x => x.HP).ToList();
}

因此,最终返回类型不可避免地必须是对象。看起来您返回了一个列表或null,因此返回类型可能是IEnumerable?

https://learn.microsoft.com/en-us/dotnet/api/system.collections.ienumerable?view=net-5.0

但我很快发现我无法将其转换回原来的类型(例如List(,因为"我不知道它是什么类型的"!

如果可以有多种类型,您必须测试您拥有的类型,例如

var filtered = mylist.Filter(FilterType.Alignment);
var processed = filtered switch {
List<AlignmentType> lat => // do something
_ => throw new Exception("not supported")
};

https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/switch-expression

您似乎想要一种灵活的方法来选择/映射base的实例到各种类型的子属性。这是正确的吗?如果是的话:

public static List<T> Map<T>(this List<Base> bases, Func<Base, T> mapper) =>  bases.Select(mapper).ToList();

用法:

List<Base> bases = ...
List<FactionType> mappedFactions = bases.Map(b => b.Faction);
List<AlignmentType> mappedAligntments = bases.Map(b => b.Alignment);
List<int> mappedHPs = bases.Map(b => b.HP);

如果没有,那么@litelite建议让返回类型都实现一个公共接口也是我会采取的方法。

最新更新