将匿名类型传递给IComparer <t> </t>

时间:2012-07-26 12:24:15

标签: c# .net-3.5 anonymous-types

我想根据viewmodel中的2个属性来比较我的viewmodel集合。 我需要的是根据startdate对视图模型进行排序,但如果enddate比今天更低,它应该放在集合的底部 关于订购完成后应如何填写的示例:

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个属性对集合进行排序?

4 个答案:

答案 0 :(得分:3)

您可以通过虚拟模板值和类型推断来实现。但是,您需要一个非泛型类,其中包含泛型方法。

您可能希望查看实现所有这些内容的MiscUtil中的ProjectionComparer。例如:

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

(请注意,我不记得off / true offhand的顺序 - 你可能需要反转EndDate的比较。)

答案 1 :(得分:2)

使用EndDate&lt;放置所有项目今天在底部,然后按StartDate对所有内容进行排序:

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

答案 2 :(得分:0)

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

答案 3 :(得分:0)

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