使用 SequenceEqual 传递通用 EquaityComparer
Pass generic EquaityComparer with SequenceEqual
我正在更新问题,以便更清楚:
我正在尝试构建用于过滤记录的 LINQ 表达式。
例如:
public string Name {get; set;}
public List<string> Score { get; set; }
public Student(string name, List<string> list=null)
{
Name=name;
Score=list;
}
我有这些学生的名单:
List<Student> listStudent = new List<Student>
{ new Student("Jane", new List<string>{"A","B"}),
new Student("Joe", new List<string>{"B", "C"}),
new Student("Jack")};
现在,我只想获取分数与给定列表匹配的学生:
List<string> scoresToCompare=new List<string>{"B", "C"};
var Result= listStudent.Where(x =>x.Score!=null ? scoresToCompare.SequenceEqual(x.Score, new StringComparer<string>()): false)
我的 StringComparer 在比较时忽略大小写:
class StringComparer<T> : IEqualityComparer<T>
{
public bool Equals(T x, T y)
{
//Check whether the compared objects reference the same data.
if (Object.ReferenceEquals(x, y)) return true;
//Check whether any of the compared objects is null.
if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
return false;
//Ignore case when comparing.
return x.ToString().Equals(y.ToString(), StringComparison.InvariantCultureIgnoreCase);
}
public int GetHashCode(T item)
{
//Check whether the object is null
if (Object.ReferenceEquals(item, null)) return 0;
//Get hash code for the Name field if it is not null.
int hashCode = item == null ? 0 : item.GetHashCode();
//Calculate the hash code for the product.
return hashCode;
}
}
现在,直到运行时我才知道列表中项目的类型,所以我试图构建一个表达式来实现相同的结果。
Type typeOfItemInList = listStudent.FirstOrDefault().GetType(); //Not the exact code, but thats how I get the type
如何使用 stringComparer 调用 sequenceEqual 方法?
var callSequenceEqualMethodWithComparer= Expression.Call(typeof(System.Linq.Enumerable), "SequenceEqual", new Type[] typeOfItemsInList }, new Expression[] { listToCompare1, listToCompare2, **stringComparer**});
最后我还需要做一个 Expression.Condition 来检查 x.Score !=null 是否通过以下方式避免空异常:
Expression.Condition(Expression.NotEqual(expressionOfList1, Expression.Constant(null)), Expression.Convert(Expression.Call(callSequenceEqualMethodWithComparer, expressionOfList1, expressionOdList2), typeof(bool)), Expression.Default(typeof(bool)) );
提前致谢!
您可以通过调用 Expression.New()
.
创建一个创建对象的表达式
要获取类型,您可以使用 typeof(StringComparer<>)
获取 StringComparer<T>
的开放泛型类型,然后在其上调用 MakeGenericType()
获取封闭类型,例如 StringComparer<string>
.
合计:
Expression.New(typeof(StringComparer<>).MakeGenericType(typeOfItemInList))
我正在更新问题,以便更清楚:
我正在尝试构建用于过滤记录的 LINQ 表达式。
例如:
public string Name {get; set;}
public List<string> Score { get; set; }
public Student(string name, List<string> list=null)
{
Name=name;
Score=list;
}
我有这些学生的名单:
List<Student> listStudent = new List<Student>
{ new Student("Jane", new List<string>{"A","B"}),
new Student("Joe", new List<string>{"B", "C"}),
new Student("Jack")};
现在,我只想获取分数与给定列表匹配的学生:
List<string> scoresToCompare=new List<string>{"B", "C"};
var Result= listStudent.Where(x =>x.Score!=null ? scoresToCompare.SequenceEqual(x.Score, new StringComparer<string>()): false)
我的 StringComparer 在比较时忽略大小写:
class StringComparer<T> : IEqualityComparer<T>
{
public bool Equals(T x, T y)
{
//Check whether the compared objects reference the same data.
if (Object.ReferenceEquals(x, y)) return true;
//Check whether any of the compared objects is null.
if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
return false;
//Ignore case when comparing.
return x.ToString().Equals(y.ToString(), StringComparison.InvariantCultureIgnoreCase);
}
public int GetHashCode(T item)
{
//Check whether the object is null
if (Object.ReferenceEquals(item, null)) return 0;
//Get hash code for the Name field if it is not null.
int hashCode = item == null ? 0 : item.GetHashCode();
//Calculate the hash code for the product.
return hashCode;
}
}
现在,直到运行时我才知道列表中项目的类型,所以我试图构建一个表达式来实现相同的结果。
Type typeOfItemInList = listStudent.FirstOrDefault().GetType(); //Not the exact code, but thats how I get the type
如何使用 stringComparer 调用 sequenceEqual 方法?
var callSequenceEqualMethodWithComparer= Expression.Call(typeof(System.Linq.Enumerable), "SequenceEqual", new Type[] typeOfItemsInList }, new Expression[] { listToCompare1, listToCompare2, **stringComparer**});
最后我还需要做一个 Expression.Condition 来检查 x.Score !=null 是否通过以下方式避免空异常:
Expression.Condition(Expression.NotEqual(expressionOfList1, Expression.Constant(null)), Expression.Convert(Expression.Call(callSequenceEqualMethodWithComparer, expressionOfList1, expressionOdList2), typeof(bool)), Expression.Default(typeof(bool)) );
提前致谢!
您可以通过调用 Expression.New()
.
要获取类型,您可以使用 typeof(StringComparer<>)
获取 StringComparer<T>
的开放泛型类型,然后在其上调用 MakeGenericType()
获取封闭类型,例如 StringComparer<string>
.
合计:
Expression.New(typeof(StringComparer<>).MakeGenericType(typeOfItemInList))