2012-07-26 67 views
0

我想比较我的viewmodel的集合,它基于viewmodel中的两个属性。 我需要的是根据startdate对我的视图模型进行排序,但是如果结尾日期与今天一样低,它应该放置在集合的底部 在完成排序之后它应该如何应用的示例:传递一个匿名类型到IComparer <T>

Stardate Enddate  
25/06/2012 25/06/2022  
21/06/2012 21/04/2018  
31/06/2012 02/07/2012  
28/06/2012 01/07/2012 

我想,这应该叫,像这样:

bankPolicyViewModels.OrderBy(vm => new {StartDate = vm.BankAccountViewModel.StartDateIRA, 
             EndDate = vm.BankAccountViewModel.EndDateIRA}, 
             new ComparerForAnonymousType); 

但我无法弄清楚如何定义比较器。 目前,我只带了这一点:

public class ComparerForAnonymousType<T> : IComparer<T> 
     where T : class 
{ 
    public int Compare(T x, T y) 
    { 
     throw new NotImplementedException(); 
    } 
} 

我可以尝试通过反射来解决已定义的属性,但是这将是很容易的出路(也表现重型我猜)。

是否有某种方法可以将匿名类型定义为T,或者是否有其他方法可以根据2个属性对集合进行排序?

回答

3

您可以通过虚拟模板值和类型推断来实现。尽管如此,你仍然需要一个非泛型的类。

你可能想看看在MiscUtil它实现所有这一切。因此,例如:

var dummy = new { StartDate = default(DateTime), 
        EndDate = default(DateTime) }; 
var now = DateTime.Now; 
var comparer = ProjectionComparer.Create(dummy, x => x.EndDate >= now) 
           .ThenBy(x => x.StartDate); 

在另一方面,你已经在使用LINQ,它可能更有意义使用OrderBy(x => x.StartDate).ThenBy(x => x.EndDate)下手......

var now = DateTime.Now; 
var ordered = bankPolicyViewModels.OrderBy(vm => vm.EndDate >= now) 
            .ThenBy(vm => vm.StartDate); 

(请注意,我可以“记得了假/真副手的顺序 - 你可能需要扭转对EndDate比较)

+0

哇,我现在觉得很愚蠢,不知道'.ThenBy()',在铱星的答案中也提到过。 'ProjectionComparer'看起来也很有趣,它会很快检查出来,但与其他解决方案相比,它增加了太多的复杂性。 – 2012-07-26 13:22:42

0

使两个视图模型都实现一个接口,该接口定义要比较的属性,然后使比较器在该接口上运行。

2

把所有的物品与结束日期今天<在底部,然后排序开始日期都可以使用:

var today = DateTime.Today; 
bankPolicyViewModels 
    .OrderBy(vm => vm.BankAccountViewModel.EndDateIRA < today ? 1 : 0); 
    .ThenBy(vm => vm.BankAccountViewModel.StartDateIRA); 
0

您可以在BankAccountViewModel类中实现接口IComparable<T>,这样您就可以使用该类的所有属性。或者表示接口IComparer<T>的基本BankAccountViewModel类继承约束。