如何使这种通用方法更灵活?

时间:2010-12-20 21:59:58

标签: c# generics anonymous-types

我正在使用一个库(Gtk中的TreeView是特定的),它允许您通过传递比较两行的函数进行排序。函数签名的简化版本可能如下所示:

int SomeSortFunc (Foo foo1, Foo foo2)
{
    // Return -1 if foo1 < foo2, 0 if foo1 == foo2, 1 if foo1 > foo2
}

我不能简单地实现Foo.CompareTo (Foo),因为我想根据上下文进行不同的排序。我排序的Foo中有几个字段。每个字段的排序优先级取决于上下文。我想写这样的东西:

int SortFunc<T> (Foo foo1, Foo foo2, params Func<Foo, T> [] selectors)
    where T : IComparable<T>
{
    return selectors
        .Select (s => s (foo1).CompareTo (s (foo2)))
        .FirstOrDefault (i => i != 0);
}

// Compare by SomeString, then by SomeInt, then by SomeBar
int SomeSortFunc (Foo foo1, Foo foo2)
{
    // Won't compile, because String, Int, and Bar are all different types.
    return SortFunc (foo1, foo2, f => f.SomeString, f => f.SomeInt, f => f.SomeBar);
}

这不会编译,因为TFunc<Foo, T>String Int中的Bar : IComparable<Bar>不同(换句话说,有T无法解决SortFunc<T>中的SomeType

有没有办法编写这个函数,只要每个类型IComparable<SomeType>实现{{1}},每个选择器都可以返回不同的类型?

1 个答案:

答案 0 :(得分:3)

我会简化它并只接受一个返回非泛型IComparable的函数。现在你可以传入函数返回原语,而不需要计算你的函数实际需要的泛型类型参数的数量,因为它实际上需要为每个提供的函数提供类型参数。

int SortFunc(Foo foo1, Foo foo2, params Func<Foo, IComparable>[] selectors)