拥有通用编译器的最佳方法是什么

时间:2010-04-01 03:02:04

标签: c# generics

我有很多比较类,比较的类只是检查对象的name属性并进行字符串比较。例如:

public class ExerciseSorter : IComparer<Exercise>
{
    public int Compare(Exercise x, Exercise y)
    {
        return String.Compare(x.Name, y.Name);
    }
}

public class CarSorter : IComparer<Car>
{
    public int Compare(Car x, Car y)
    {
        return String.Compare(x.Name, y.Name);
    }
}

将此代码设置为通用的最佳方法是什么,所以我不需要一遍又一遍地编写冗余代码。

3 个答案:

答案 0 :(得分:12)

我使用这样的一个:

public class AnonymousComparer<T> : IComparer<T>
{
    private Comparison<T> comparison;

    public AnonymousComparer(Comparison<T> comparison)
    {
        if (comparison == null)
            throw new ArgumentNullException("comparison");
        this.comparison = comparison;
    }

    public int Compare(T x, T y)
    {
        return comparison(x, y);
    }
}

用法:

var carComparer = new AnonymousComparer<Car>((x, y) => x.Name.CompareTo(y.Name));

如果您正在进行直接属性比较,并且属性类型实现IComparable(例如intstring),那么,我也有这个类有点更简洁使用:

public class PropertyComparer<T, TProp> : IComparer<T>
    where TProp : IComparable
{
    private Func<T, TProp> func;

    public PropertyComparer(Func<T, TProp> func)
    {
        if (func == null)
            throw new ArgumentNullException("func");
        this.func = func;
    }

    public int Compare(T x, T y)
    {
        TProp px = func(x);
        TProp py = func(y);
        return px.CompareTo(py);
    }
}

这个用法是:

var carComparer = new PropertyComparer<Car, string>(c => c.Name);

答案 1 :(得分:3)

从.NET 4.5开始,creating a generic class不需要在Comparison<T> delegate实现中包装IComparer<T> interface

框架在Create method上提供静态Comparer<T> class,其中Comparison<T>委托并返回Comparer<T>(实现IComparer<T>)。

以下是如何使用它的示例:

// Sample comparison, any T will do.
Comparison<int> comparison = (x, y) => x.CompareTo(y)

// Get the IComparer.
IComparer<T> comparer = Comparer.Create(comparison);

现在,您可以编写执行比较的lambda表达式,并在IComparer<T>实现中快速包装那些不提供Comparison<T>委托选项的表达式(例如Sort method on List<T> class)。

答案 2 :(得分:0)

如果你的所有类都有Name属性,你可以引入IHaveName接口并创建这样的比较器:

public class NameComparer : IComparer<IHaveName>
{
    public int Compare(IHaveName x, IHaveName y)
    {
        return String.Compare(x.Name, y.Name);
    }
}