2013-12-09 5 views
0

Я получаю ObservableCollection и желаю иметь условия, а также порядок в моем конструкторе.OrderBy in constructor

следующие в порядке с условием работы, но я не могу сделать это с OrderBy :(

public class CustomCollection<TModel> : ObservableCollection<TModel> where TModel : EntityBaseClass 
{ 
    private readonly Func<TModel, bool> _condition; 

    public CustomCollection(ObservableCollection<TModel> source, Func<TModel, bool> condition) 
     : base(source.Where(condition)) 
    { 
     _condition = condition; 
    } 
} 

То, что я пытался это продлить конструктор со следующим параметром

Func<TModel, TModel> orderby 

и изменить: базовый вызов

: base(source.Where(condition).OrderBy(orderby)) 

Это создает без проблем, , но когда я пытаюсь называть это так:

new CustomCollection<TestClass>(SourceCollection, x => x.Price == 2.50, x => x.SortOrder); 

Я получаю следующее сообщение.

«Невозможно преобразовать тип выражения« строка », чтобы вернуть тип« TestClass ».

Какое любопытное имеет смысл, поскольку мое состояние имеет

Func<TModel, TModel> condition 

который является TestClass указанный в два раза, когда я смотрю на реализации OrderBy я могу увидеть TSource и TKEY, но, как я в состоянии указать TKey в моем случае?

Надеюсь, вы можете мне помочь.

ответ

4

Вам нужно добавить новый общий аргумент, чтобы представить тип, с которым переключается селектор orderby. Селектор в вашем случае вынужден выбрать что-то того же типа, что и сам объект модели, но на самом деле вы этого не хотите.

public class CustomCollection<TModel, TSortKey> : ObservableCollection<TModel> 
    where TModel : EntityBaseClass 
{ 
    private readonly Func<TModel, bool> _condition; 
    private readonly Func<TModel, TSortKey> sortSelector; 

    public CustomCollection(ObservableCollection<TModel> source, 
     Func<TModel, bool> condition, 
     Func<TModel, TSortKey> sortSelector) 
     : base(source.Where(condition).OrderBy(sortSelector)) 
    { 
     _condition = condition; 
     this.sortSelector = sortSelector; 
    } 
} 
+0

С этим я вынужден инициализировать с помощью нового CustomCollection (....); или? –

+2

@RandRandom Аргумент второго типа должен быть типом того, что вы сортируете, а не вашей моделью (если это не то, что вы сортируете). Вы также можете создавать общие заводские методы, а не использовать конструктор, чтобы вы могли использовать вывод типового типа. – Servy

+0

Не могли бы вы предложить решение упомянутой альтернативы (заводская фабрика)? –

0

Изменить ваш orderbyFunc вернуть object:

Func<TModel, object> orderBy 

Метод OrderBy достаточно умен, чтобы работать в таком случае (при условии, ваши ключевые орудия IComparable). Самым большим недостатком этого, по сравнению с добавлением другого универсального типа, такого как решение Servy, является то, что вы не можете указать строго типизированный IComparer<>, чтобы идти вместе с ним (вам нужно указать IComparer<object>, который отличает перед сравнением).

+0

@downvoter: помочь объяснить? Сдвиг был неожиданно быстрым. Быстрее, чем я ожидал, что человек сможет это сделать - конечно, быстрее, чем человек может прочитать мой ответ и знать, заслуживает ли он нисходящего хода. –

+0

countervote, с момента его работы спасибо. –