C#实现兼容泛型数组与List的随机取元素扩展方法
问题背景
我正在为泛型数组编写扩展方法,实现从中随机抽取元素集合的功能。此前我已经为List<T>类型编写了一套扩展方法,运行效果良好,但没办法把相同逻辑直接迁移适配泛型数组,已有的List版本代码如下:
public static T Random<T>(this List<T> list) { return list[GameManager.instance.functions.RandomInt(list.Count - 1)]; } public static IEquatable Random<IEquatable>(this List<IEquatable> list, List<IEquatable> hits) { int rand = GameManager.instance.functions.RandomInt(list.Count - 1); while (hits.Exists(h => h.Equals(list[rand]))) rand = GameManager.instance.functions.RandomInt(list.Count - 1); return list[rand]; } public static List<T> Random<T>(this List<T> list, int count) { List<T> result = new List<T>(); for (int i = 0; i < count; i++) { result.Add(list.Random()); } return result; } public static List<IEquatable> RandomUnique<IEquatable>(this List<IEquatable> list, int count) { List<IEquatable> result = new List<IEquatable>(); for (int i = 0; i < count; i++) { result.Add(list.Random(result)); } return result; }
最开始我尝试把第一个方法改成如下形式:
public static IEnumerable Random<IEnumerable>(this IEnumerable list)
但这种写法下无法将入参识别为数组类型,拿不到长度属性。我知道一种临时解决方案:先把数组转成List,获取随机值后再转回数组,但对于仅需从4元素数组中抽取2个随机元素这类简单场景,这种转换的操作开销过大,因此想找更合理的实现方案。
解决迭代
第一次更新
感谢评论区Mathew的帮助,我先写出了正确适配泛型数组的单元素随机抽取扩展方法:
public static T Random<T>(this T[] list) { return list[GameManager.instance.functions.RandomInt(list.Length - 1)]; }
后续我还参考Dmitry的回答,尝试实现适配IEnumerable的版本。
第二次更新
感谢Zastai的帮助,我修改了所有方法,现在这套扩展可以同时兼容List与泛型数组:
public static T Random<T>(this IReadOnlyList<T> list) { return list[GameManager.instance.functions.RandomInt(list.Count - 1)]; } public static IEquatable Random<IEquatable>(this IReadOnlyList<IEquatable> list, List<IEquatable> hits) { int rand = GameManager.instance.functions.RandomInt(list.Count - 1); while (hits.Exists(h => h.Equals(list[rand]))) rand = GameManager.instance.functions.RandomInt(list.Count - 1); return list[rand]; } public static List<T> Random<T>(this IReadOnlyList<T> list, int count) { List<T> result = new(); for (int i = 0; i < count; i++) { result.Add(list.Random()); } return result; } public static List<IEquatable> RandomUnique<IEquatable>(this IReadOnlyList<IEquatable> list, int count) { List<IEquatable> result = new(); for (int i = 0; i < count; i++) { result.Add(list.Random(result)); } return result; }
这个版本暂时不支持直接对字符串类型调用(例如"abcdefg".Random()),但已经完全满足我的使用需求。
内容的提问来源于stack exchange,提问作者Arkadiusz Galler
相关产品推荐
相关产品推荐

