Tho*_*ook 2 c# syntax open-closed-principle
我正在尝试创建一种优雅且可扩展的查询字典的方法,该字典将枚举映射到一组字符串.
所以我有这个SearchFragments
包含字典的类.然后我想要一个方法,其中这个类的消费者可以简单地问"HasAny",这是我正在努力的位,只需传递一些查询,如表达式并获得布尔答案.
public class SearchFragments
{
private readonly IDictionary<SearchFragmentEnum, IEnumerable<string>> _fragments;
public SearchFragments()
{
_fragments = new Dictionary<SearchFragmentEnum, IEnumerable<string>>();
}
public bool HasAny(IEnumerable<SearchFragmentEnum> of)
{
int has = 0;
_fragments.ForEach(x => of.ForEach(y => has += x.Key == y ? 1 : 0));
return has >= 1;
}
}
Run Code Online (Sandbox Code Playgroud)
目前的问题是,这个类的消费者现在必须构建一个IEnumerable<SearchFragmentEnum>
可能非常混乱的消费者.
我正在寻找的是消费代码将能够写出以下内容:
searchFragments.HasAny(SearchFragmentEnum.Name, SearchFragmentEnum.PhoneNumber)
Run Code Online (Sandbox Code Playgroud)
但是这个参数列表的大小可能会有所不同(没有我必须在SearchFragments
类中为每个可能的组合编写方法重载(这样如果SearchFragmentEnum
在将来的日期添加新值,我将不必更新类.
您可以使用 params[]
public bool HasAny(params SearchFragmentEnum[] of)
{ ...
Run Code Online (Sandbox Code Playgroud)
旁注:您知道LIN(Q)查询应该只查询源并且不会引起任何副作用吗?但是您的查询会不必要地增加整数:
_fragments.ForEach(x => of.ForEach(y => has += x.Key == y ? 1 : 0));
Run Code Online (Sandbox Code Playgroud)
而是使用它(这也更有效,更可读):
return _fragments.Keys.Intersect(of).Any();
Run Code Online (Sandbox Code Playgroud)
更有效的替代方案是谢尔盖的想法:
return of?.Any(_fragments.ContainsKey) == true;
Run Code Online (Sandbox Code Playgroud)