我有一个计算列表的方法。在算法中的某些点,需要从列表中选择单个元素。选择哪个元素并不重要,但我想将其留给用户来决定。
现在,我添加了一个扩展方法 IList.Random()
,它只接受一个随机元素。 .First()
也同样有效。假设我想让用户选择使用哪种方法,或者可能是一种完全不同的方法,那会是什么样子?
我正在考虑使用选项有限的枚举,然后我可以将每个调用包装在一个开关中并调用适当的函数。 但也许某种 lambda 函数会更合适?
此方法需要在两个不同的地方使用,一次在 List
上,一次在 List
上。我想对两者使用相同的方法。
这不是 GUI 应用程序。我正在尝试决定如何设计 API。
具体来说,我想要一个像
public Func<IList<T>, T> SelectElement = list => list.First();
Which 这样的字段,然后在方法中使用,
public string Reverse(string pattern, IList<object> args = null, IDictionary<string, object> kwargs = null)
但通用字段是不可能的。所以我正在寻找替代解决方案。一种方法是使 SelectElement
方法成为 Reverse() 的参数,然后我可以使其通用......但我希望将其保留在类级别以实现可重用性。如果我可以帮助的话,不想再向该函数传递任何参数。
编辑: 完整源代码
I've got a method that computes a list. At certain points in the algorithm a single element from the list needs to be chosen. It doesn't really matter which element is chosen, but I'd like to leave it up to the user to decide.
Right now, I've added an extension method IList<T>.Random()
which simply takes a random element. .First()
would have worked equally as well. Supposing I want to let the user pick which method is used, or perhaps an entirely different method, how would that look?
I was thinking about using an enum with limited options, and then I could wrap each of these calls in a switch and call the appropriate function. But maybe some sort of lambda function would be more appropriate?
This method needs to be used in two different places, once on a List<char>
and once on a List<string>
. I want to use the same method for both.
This isn't a GUI app. I'm trying to decide how to design the API.
Specifically, I want to have a field like
public Func<IList<T>, T> SelectElement = list => list.First();
Which would then be used in the method,
public string Reverse(string pattern, IList<object> args = null, IDictionary<string, object> kwargs = null)
But generic fields aren't possible. So I'm looking for an alternative solution. One would be to make the SelectElement
method an argument to Reverse(), then I could make it generic... but I was hoping to keep it at a class-level for re-usability. Don't want to pass any more args to the function if I can help it.
Edit: full source code
发布评论
评论(4)
这个怎么样:
how about this:
这是我使用通用方法组合而成的一个非常基本的示例,该方法采用
Func, T>
来从列表中选择一个项目,然后返回结果。我已经做了一些如何调用它的示例:如果您想限制用户的选择,您可以遵循枚举的路线并将此方法设为私有方法,然后有一种方法将枚举转换为适当的方法选择器委托传递给底层私有方法。
Here's an extremely basic example I put together using a generic method that takes in a
Func<IEnumerable<T>, T>
for selecting an item from the list and then returns the result. I've done a few examples of how to call it:If you want to limit the choices a user has you could follow the route of an enum and make this method a private method and then have a way to convert the enum to the appropriate selector delegate to pass to the underlying private method.
我可以使匿名方法在对象上工作,从而避免泛型,然后添加一个辅助方法,这就是我实际用来调用它的方法。有点丑,但似乎有用。
I can make the anonymous method work on objects, thereby avoiding generics, and then add a helper method which is what I'll actually use to call it. A little ugly, but seems to work.
这适用于字符和字符串。尚未测试其他类型。在我看到 Ralph 的代码之前构建了这个,它实际上是相同的。
LINQPad代码:
This works for chars and strings. Haven't tested with other types. Built this before I saw Ralph's code, which is practically the same.
LINQPad code: