这让我很难受,因为我觉得我以前见过一些东西,但我的搜索结果是空的,而且我还没有记住各种模式(还)。
现状
我有一个搜索网格,允许用户根据多个属性进行过滤。用户想要的过滤器通过 NameValueCollection
传入并解析出来。
目前,我们的旧应用程序在单独的 if 语句中检查每个潜在的过滤器,然后运行自定义代码。由于圈复杂度不是我的菜,30 个几乎相同的 if
语句让我很烦。
迈向更好的道路
我没有继续以硬编码的方式检查每个项目,而是重新编写了解析器,这样我现在可以快速获得将应用的所有过滤器的列表。我还将过滤器本身重构到它们自己的类中。
因此,我有一个字符串形式的过滤器列表(“Name”、“BirthDate”等)和一堆类(NameFilter
、BirthDateFilter
、等等)
问题
获取表示过滤器名称的字符串列表并将其转换为这些过滤器对象本身的列表的良好、标准方法是什么?
我想我可以用 LocateFilter(string filterName)
方法做一些 FilterLocator
,但这似乎会导致一个长的 switch 语句并且看起来很好漂白剂。
我感觉这正朝着某种 IoC/DI 解决方案发展,但我对这两者的了解还不足以完全实现它。
谢谢你的想法!
最佳答案
使用字典,其中键是您的过滤器名称,值是您的过滤器对象。
与其硬编码该字典,不如创建一个自定义属性,为每个过滤器对象指定一个过滤器名称。然后,使用反射找到那些对象并创建一个静态字典以备后用。这样,就完全没有对各个过滤器映射进行硬编码。
这是为此设置的示例:
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class FilterNameAttribute : Attribute
{
public FilterNameAttribute(string filterName)
{
FilterName = filterName;
}
public string FilterName { get; private set; }
}
[FilterName("MyFilterName")]
public class MyFilter
{
//Do whatever you want here
}
public static class FilterHelper
{
static Dictionary<string, Type> _filterTypesDict;
static FilterHelper()
{
var assembly = Assembly.GetExecutingAssembly();
_filterTypesDict = assembly.GetTypes()
.Select(type => new { type, attrib = (FilterNameAttribute)type.GetCustomAttributes(typeof(FilterNameAttribute), false).FirstOrDefault() })
.Where(x => x.attrib != null)
.ToDictionary(x => x.attrib.FilterName, x => x.type);
}
public static Type GetFilterType(string filterName)
{
Type filterType;
if (!_filterTypesDict.TryGetValue(filterName, out filterType))
{
throw new Exception("Unknown Filter Name.");
}
return filterType;
}
public static object GetFilter(string filterName)
{
return Activator.CreateInstance(GetFilterType(filterName));
}
}
关于c# - 基于字符串列表返回对象的模式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23394821/