C# 如何使这些方法通用?
我有一些字典都是这种类型的C# 如何使这些方法通用?,c#,generics,methods,C#,Generics,Methods,我有一些字典都是这种类型的 Dictionary<Guid, string> 字典 我有很多方法,基本上做相同的事情,但使用不同的参数做不同的事情。下面是一些示例方法 private IQueryable<SomeClass> FilterContacts(Filter filter, IQueryable<SomeClass> query) { if (filter.Contacts != null &&a
Dictionary<Guid, string>
字典
我有很多方法,基本上做相同的事情,但使用不同的参数做不同的事情。下面是一些示例方法
private IQueryable<SomeClass> FilterContacts(Filter filter,
IQueryable<SomeClass> query)
{
if (filter.Contacts != null && filter.Contacts.Any())
{
result = result.Where(x => filter.Contacts.Contains(x.ContactID));
}
return result;
}
private IQueryable<SomeClass> FilterSomethingElse(Filter filter,
IQueryable<SomeClass> query)
{
if (filter.SomethingElse != null && filter.SomethingElse.Any())
{
result = result.Where(x => filter.SomethingElse.Contains(x.SomethingElseID));
}
return result;
}
private IQueryable过滤器触点(过滤器过滤器、,
IQueryable查询)
{
if(filter.Contacts!=null&&filter.Contacts.Any())
{
result=result.Where(x=>filter.Contacts.Contains(x.ContactID));
}
返回结果;
}
专用可更换过滤器或铰链(过滤器、,
IQueryable查询)
{
if(filter.SomethingElse!=null&&filter.SomethingElse.Any())
{
result=result.Where(x=>filter.SomethingElse.Contains(x.SomethingElseID));
}
返回结果;
}
因此,所有这些方法共享相同的结构,但在筛选器和where子句中使用不同的属性。有没有一种方法可以让这种方法足够通用,我只需要一种方法就可以做到这一点?在这种情况下,策略模式似乎是合适的 策略模式允许您定义一系列可在运行时选择的可互换算法。要定义算法,可以执行以下操作:
public interface IFilterStrategy<T>
{
IQueryable<T> Filter(Filter filter, IQueryable<T> query);
}
public class FilterContacts : IFilterStrategy<SomeClass>
{
public IQueryable<T> Filter(Filter filter, IQueryable<T> query)
{
if (filter.Contacts != null && filter.Contacts.Any())
{
result = result.Where(x => filter.Contacts.Contains(x.ContactID));
}
return result;
}
}
public class FilterSomethingElse : IFilterStrategy<SomeClass>
{
public IQueryable<T> Filter(Filter filter, IQueryable<T> query)
{
if (filter.SomethingElse != null && filter.SomethingElse.Any())
{
result = result.Where(x => filter.SomethingElse.Contains(x.SomethingElseID));
}
}
}
公共接口策略
{
IQueryable过滤器(过滤器过滤器、IQueryable查询);
}
公共类筛选器联系人:IFilterStrategy
{
公共IQueryable筛选器(筛选器筛选器、IQueryable查询)
{
if(filter.Contacts!=null&&filter.Contacts.Any())
{
result=result.Where(x=>filter.Contacts.Contains(x.ContactID));
}
返回结果;
}
}
公共类筛选器Somethingelse:IFilterStrategy
{
公共IQueryable筛选器(筛选器筛选器、IQueryable查询)
{
if(filter.SomethingElse!=null&&filter.SomethingElse.Any())
{
result=result.Where(x=>filter.SomethingElse.Contains(x.SomethingElseID));
}
}
}
然后如何实现这一点取决于类的设计和预期用途。其中一些实现是常见的:
IFilterStrategy
实例IFilterStrategy
的私有字段,您可以使用private set()方法进行切换在任何情况下,您都可以在实际类中维护一个
Filter()
方法,该方法将使用指定的策略模式类。以下解决方案使用委托作为参数,以注入一些必要的逻辑,使该方法更通用
private IQueryable<SomeClass> FilterCommon(IQueryable<SomeClass> query
, Filter filter
, Func<Filter, Dictionary<Guid, string>> getDictionary
, Func<SomeClass, Guid> getKey)
{
IQueryable<SomeClass> result = null;
Dictionary<Guid, string> commonDictionary = getDictionary(filter);
if (commonDictionary != null && commonDictionary.Any())
{
result = query.Where(x => commonDictionary.ContainsKey(getKey(x)));
}
return result;
}
private IQueryable过滤器common(IQueryable查询
,过滤器
,Func getDictionary
,Func getKey)
{
IQueryable结果=null;
Dictionary commonDictionary=getDictionary(过滤器);
if(commonDictionary!=null&&commonDictionary.Any())
{
result=query.Where(x=>commonDictionary.ContainsKey(getKey(x));
}
返回结果;
}
我认为过滤器参数不是必需的,因此可以简化为:
private IQueryable<SomeClass> FilterCommon(IQueryable<SomeClass> query
, Dictionary<Guid, string> commonDictionary
, Func<SomeClass,Guid> getKey)
{
IQueryable<SomeClass> result = null;
if (commonDictionary != null && commonDictionary.Any())
{
result = query.Where(x => commonDictionary.ContainsKey(getKey(x)));
}
return result;
}
private IQueryable过滤器common(IQueryable查询
,字典
,Func getKey)
{
IQueryable结果=null;
if(commonDictionary!=null&&commonDictionary.Any())
{
result=query.Where(x=>commonDictionary.ContainsKey(getKey(x));
}
返回结果;
}
用法:
//Initializing a few things first...
Filter myFilter = new Filter();
IQueryable<SomeClass> query = new Queryable();//Just a generated type
//This is for my first example from above
FilterCommon(query, myFilter, x => x.Contacts, x => x.ContactID);
//Second example without filter parameter
FilterCommon(query, myFilter.Contacts, x => x.ContactID);
FilterCommon(query, myFilter.SomethingElse, x => x.SomethingElseID);
//先初始化几件事。。。
过滤器myFilter=新过滤器();
IQueryable query=new Queryable()//只是一个生成的类型
//这是我上面的第一个例子
FilterCommon(查询,myFilter,x=>x.Contacts,x=>x.ContactID);
//第二个不带过滤器参数的示例
FilterCommon(查询,myFilter.Contacts,x=>x.ContactID);
FilterCommon(查询,myFilter.SomethingElse,x=>x.SomethingElseID);
这看起来是策略模式的一个很好的候选。联系人的类型是否都是字典
?你能不能把它作为一个参数而不是Filter-Filter
?当然这是有道理的,但是我认为有一种简单的方法可以用一个方法进行过滤,而不是现在有一堆实现IFilterStrategy的类。另外,我会有15个这样的过滤器。@Matthew可能不确定我的问题是否正确,但如果所有的filter.Class都是某种集合,为什么不能传递集合本身并搜索它们或类似的内容:private IQueryable FilterContacts(filter filter,dynamic someClass,string属性){var searchfrom=someClass.GetType().GetProperty(property).GetValue(filter,null);这更像是我在想的。让我看看我是否可以用它来做一些事情。