如何指定列表选择方法?

我有一个计算列表的方法。 在算法的某些点处,需要选择列表中的单个元素。 选择哪个元素并不重要,但我想将其留给用户来决定。

现在,我添加了一个扩展方法IList.Random()IList.Random()需要一个随机元素。 .First()也同样有效。 假设我想让用户选择使用哪种方法,或者可能是一种完全不同的方法,那会是什么样子?

我正在考虑使用有限选项的枚举,然后我可以将每个调用包装在一个开关中并调用相应的函数。 但也许某种lambda函数会更合适

此方法需要在两个不同的位置使用,一次在List ,一次在List 。 我想对两者使用相同的方法。


这不是一个GUI应用程序。 我正在尝试决定如何设计API。

具体来说,我希望有一个像这样的领域

 public Func<IList, T> SelectElement = list => list.First(); 

然后将在该方法中使用,

  public string Reverse(string pattern, IList args = null, IDictionary kwargs = null) 

但通用字段是不可能的。 所以我正在寻找替代解决方案。 一种方法是将SelectElement方法作为Reverse()的参数,然后我可以使它成为通用的…但我希望将它保持在类级别以便重新使用。 如果我可以帮助它,不想再将args传递给函数。

编辑: 完整的源代码

这个怎么样:

 public class MyClass { public static class C { public static Func, T> SelectElement; } public int Test(IList list) { return C.SelectElement(list); } } static class Program { static void Main(string[] args) { MyClass.C.SelectElement = xs => xs.First(); MyClass.C.SelectElement = xs => xs.First(); var list = new List(new int[] { 1, 2, 3 }); var c = new MyClass(); var v = c.Test(list); Console.WriteLine(v); } } 

这是我使用generics方法放在一起的一个非常基本的例子,该方法接受Func, T>用于从列表中选择项目然后返回结果。 我已经做了一些如何调用它的例子:

 using System; using System.Collections.Generic; using System.Linq; namespace Test { class Program { static void Main(string[] args) { //Simple list. var list = new List { 1, 2, 3, 4 }; // Try it with first var result = DoItemSelect(list, Enumerable.First); Console.WriteLine(result); // Try it with last result = DoItemSelect(list, Enumerable.Last); Console.WriteLine(result); // Try it with ElementAt for the second item (index 1) in the list. result = DoItemSelect(list, enumerable => enumerable.ElementAt(1)); Console.WriteLine(result); } public static T DoItemSelect(IEnumerable enumerable, Func, T> selector) { // You can do whatever you method does here, selector is the user specified func for // how to select from the enumerable. Here I just return the result of selector directly. return selector(enumerable); } } } 

如果要限制用户的选择,可以遵循枚举的路径并使此方法成为私有方法,然后有一种方法将枚举转换为适当的选择器委托以传递给底层私有方法。

 public Func, object> SelectElement = list => list.First(); private T _S(IEnumerable list) { return (T)SelectElement(list.Cast().ToList()); } 

我可以让匿名方法处理对象,从而避免generics,然后添加一个帮助方法,这是我实际用来调用它。 有点难看,但似乎工作。

这适用于字符和字符串。 没有测试过其他类型。 在我看到Ralph的代码之前构建了它,这几乎是相同的。

LINQPad代码:

 void Main() { var chars = new List(); var strings = new List(); chars.AddRange(new char[] {'1','2','4','7','8','3'}); strings.AddRange(new string[] {"01","02","09","12","28","52"}); chars.Dump(); strings.Dump(); Func, string> SelectFirst = ( list ) => list.First().ToString(); Func, string> SelectLast = ( list ) => list.Last().ToString(); Func, string> SelectRandom = ( list ) => list.ElementAt( new Random().Next(0, list.Count())).ToString(); SelectBy(SelectFirst, strings.Cast().ToList()).Dump(); SelectBy(SelectFirst, chars.Cast().ToList()).Dump(); SelectBy(SelectLast, strings.Cast().ToList()).Dump(); SelectBy(SelectLast, chars.Cast().ToList()).Dump(); SelectBy(SelectRandom, strings.Cast().ToList()).Dump(); SelectBy(SelectRandom, chars.Cast().ToList()).Dump(); } private string SelectBy(Func, string> func, IList list) { return func(list); }