2016-07-15 2 views
0

Я обновляю этот вопрос, чтобы быть более ясным:Pass родовое EquaityComparer с 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 

Как я могу вызвать метод sequenceEqual с помощью stringComparer?

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))); 

Заранее спасибо!

+1

Это действительно трудно сказать, что вы делаете из этих изолированных утверждений с использованием переменных, которые не были показаны. Пожалуйста, предоставьте [mcve] с последними и фактическими результатами. (Но нет, вы не должны сами называть Equals - и не ясно, что вы ожидаете делать на шаге 2, когда вы уже прошли сравнение на шаге 1 ...) –

+0

Почему вы создаете Сравнение равенств вместо использования SequenceEqual? – lstern

+0

Поскольку SequenceEqual является случайным. Мне нужно, чтобы сравнение было нечувствительным к регистру – Newbee

ответ

0

Вы можете создать выражение, которое создает объект, вызывая Expression.New().

Чтобы получить тип, вы можете использовать typeof(StringComparer<>), чтобы получить открытый универсальный тип для StringComparer<T>, а затем вызвать MakeGenericType() на нее, чтобы получить закрытый тип, например StringComparer<string>.

Соединенные:

Expression.New(typeof(StringComparer<>).MakeGenericType(typeOfItemInList)) 
+0

svick - Работал как шарм - огромное спасибо! Я вызвал SequenceEqual со строковым сравнением следующим образом: var callSequenceEqualMethodWithComparer = Expression.Call (typeof (System.Linq.Enumerable), "SequenceEqual", новый тип [] typeOfItemsInList}, новое выражение [] {listToCompare1, listToCompare2, выражение .new (TypeOf (StringComparer <>) MakeGenericType (typeOfItemInList).)}); И это прекрасно работает. Мне просто пришлось немного изменить предыдущий код, чтобы вызвать метод SequenceEqual с тремя параметрами. Еще раз спасибо. – Newbee

Смежные вопросы