C#针对具有相同属性的两个不同类的列表的单个筛选例程
有两类:C#针对具有相同属性的两个不同类的列表的单个筛选例程,c#,generics,C#,Generics,有两类: public class A { public int IntProp { get; set; } public string template { get; set; } } public class B { public string name { get; set; } public string template { get; set; } } 我要创建的例程将接收列表或列表,并基于模板属性应用一些筛选。A中要避免的模板是:“b”、“bb”
public class A {
public int IntProp { get; set; }
public string template { get; set; }
}
public class B {
public string name { get; set; }
public string template { get; set; }
}
我要创建的例程将接收列表
或列表
,并基于模板
属性应用一些筛选。A
中要避免的模板是:“b”、“bb”、“bbb”,而b
中要避免的模板是:“A”、“aa”、“aaa”
所以我做了这样的事情:
static List<A> filterAsByTemplate(List<A> listOfA, string skipInAList, char separator) {
foreach (string template in skipInAList.Split(separator)) {
listOfA.RemoveAll(x => x.template.Equals(template));
}
return listOfA;
}
static List<B> filterBsByTemplate(List<B> listOfB, string skipInBList, char separator) {
foreach (string template in skipInBList.Split(separator)) {
listOfB.RemoveAll(x => x.template.Equals(template));
}
return listOfB;
}
如何组合filterAsByTemplate
和filtersbytemplate
如果“组合”是指使用单个方法对它们进行规则处理,则必须使用模板属性为a
和B
创建一个公共类型,并且该方法的参数为List
比如:
public abstract class BaseTypeOfAB
{
public string template { get; set; }
}
public class A : BaseTypeOfAB
{
public int IntProp { get; set; }
}
public class B : BaseTypeOfAB
{
public string name { get; set; }
}
static List<T> filterByTemplate<T>(List<T> list, string skipInList, char separator) where T : BaseTypeOfAB
{
foreach (string template in skipInList.Split(separator))
list.RemoveAll(x => x.template.Equals(template));
return list;
}
公共抽象类BaseTypeOfAB
{
公共字符串模板{get;set;}
}
公共A类:基本类型
{
公共int IntProp{get;set;}
}
公共B类:基本类型
{
公共字符串名称{get;set;}
}
静态列表过滤器ByTemplate(列表列表、字符串skipInList、字符分隔符),其中T:BaseTypeOfAB
{
foreach(skipInList.Split中的字符串模板(分隔符))
RemoveAll(x=>x.template.Equals(template));
退货清单;
}
或者,如果不想更改类的结构,可以传递一个泛型委托:
static List<T> filterByTemplate<T, TProp>(List<T> list, Func<T, TProp> predicate, string skipInList, char separator)
{
foreach (string template in skipInList.Split(separator)) {
list.RemoveAll(x => predicate(x).Equals(template));
return list;
}
// Usage:
var listOfAs = new List<A>();
var listOfBs = new List<B>();
filterByTemplate(listOfAs, x => x.template, "a;aa;aaa", ';');
filterByTemplate(listOfBs, x => x.template, "b;bb;bbb", ';');
静态列表过滤器ByTemplate(列表列表、Func谓词、字符串skipInList、字符分隔符)
{
foreach(skipInList.Split中的字符串模板(分隔符)){
RemoveAll(x=>谓词(x).Equals(模板));
退货清单;
}
//用法:
var listOfAs=新列表();
var listOfBs=新列表();
filterByTemplate(listOfAs,x=>x.template,“a;aa;aaa”,“;”;
filterByTemplate(listOfBs,x=>x.template,“b;bb;bbb”,“;”;
您可以这样做:
定义基类:
public abstract class BaseTypeOfAB
{
public abstract string template {get;set;}
}
而A
和B
都继承自BaseTypeOfAB
public class A : BaseTypeOfAB {
public int IntProp { get; set; }
public override string template { get; set; }
}
public class B : BaseTypeOfAB {
public string name { get; set; }
public override string template { get; set; }
}
static List<TClass> filterByTemplate<TClass>(List<TClass> ls,string skipInList,char seperator) where TClass: BaseTypeOfAB
{
return ls.Where (w =>!skipInList.Split(seperator).Contains(w.template)).ToList();
}
编写一个接受列表和跳过的通用函数。使用like查看值是否不包含在跳过中。如下所示:
public class A : BaseTypeOfAB {
public int IntProp { get; set; }
public override string template { get; set; }
}
public class B : BaseTypeOfAB {
public string name { get; set; }
public override string template { get; set; }
}
static List<TClass> filterByTemplate<TClass>(List<TClass> ls,string skipInList,char seperator) where TClass: BaseTypeOfAB
{
return ls.Where (w =>!skipInList.Split(seperator).Contains(w.template)).ToList();
}
静态列表过滤器ByTemplate(列表ls、字符串skipInList、字符分隔符),其中TClass:BaseTypeOfAB
{
返回ls.Where(w=>!skipInList.Split(separator).Contains(w.template)).ToList();
}
您可以定义一个用于过滤的接口,而不是实现一个使用该接口实现列表的过滤方法
public interface IFilterable
{
string FilterProperty { get; }
}
public class A : IFilterable
{
//implementation
}
public class B : IFilterable
{
//Implementation
}
//Declaring Filter as extension method is possible aswell:
//static IEnumerable<T> Filter(this IEnumerable<T> source, string criteria)
static IEnumerable<T> Filter(IEnumerable<T> source, string criteria)
where T : IFilterable
{
foreach(var item in source)
{
if(item.FilterProperty.Contains(criteria)) yield return item;
}
}
公共接口可过滤
{
字符串筛选器属性{get;}
}
公共A类:可过滤
{
//实施
}
公共B类:可过滤
{
//实施
}
//也可以将筛选器声明为扩展方法:
//静态IEnumerable筛选器(此IEnumerable源,字符串条件)
静态IEnumerable筛选器(IEnumerable源、字符串条件)
其中T:i可过滤
{
foreach(源中的var项)
{
如果(item.FilterProperty.Contains(criterials))生成退货项目;
}
}
代码中没有一个Linq方法。不过问题很好。你应该尽可能使用接口而不是基类。基类是一种宝贵的资源,不能像这样浪费掉。你应该尽可能使用接口而不是基类。基类是一种宝贵的资源,不能像这样浪费掉。@Aron,对我(和许多其他人)来说,接口代表一个契约。在这种情况下,模板
属性代表数据而不是行为,因此使用基类肯定是个人的偏好(在我看来,是更好的选择)。你有任何证据支持这样的说法吗“基类是一种宝贵的资源,不能像这样浪费”?a)你只能继承一个类b)vlookupcost@Arona)“您只能继承一个类”-这是一个人为的问题。b)“vlookup成本"-由于模板
属性未标记为抽象
或虚拟
,因此我不确定此处是否实际涉及虚拟表查找,并且接口调度也有成本。在运行时,CLR可以轻松有效地处理它们,并且拾取接口/类
不会添加任何内容到这里的实际问答。