2

我有一堆实现IComparable<T>. 因为这些类型实现了该接口,所以提供以下重载是有意义的:

/// <summary>Equality comparison operator.</summary>
/// <param name="lhs">The left hand side.</param>
/// <param name="rhs">The right hand side.</param>
/// <returns>True if <paramref name="lhs"/> is equal to <paramref name="rhs"/>; otherwise, false.</returns>
public static bool operator==(T lhs, T rhs)
{
    if (object.ReferenceEquals(lhs, null))
    {
        return object.ReferenceEquals(rhs, null);
    }

    return lhs.CompareTo(rhs) == 0;
}

/// <summary>Inequality comparison operator.</summary>
/// <param name="lhs">The left hand side.</param>
/// <param name="rhs">The right hand side.</param>
/// <returns>True if <paramref name="lhs"/> is not equal to <paramref name="rhs"/>; otherwise, false.</returns>
public static bool operator !=(T lhs, T rhs)
{
    return !(lhs == rhs);
}

/// <summary>Less than comparison operator.</summary>
/// <param name="lhs">The left hand side.</param>
/// <param name="rhs">The right hand side.</param>
/// <returns>True if <paramref name="lhs"/> is less than <paramref name="rhs"/>; otherwise, false.</returns>
public static bool operator <(T lhs, T rhs)
{
    if (lhs == null)
    {
        if (rhs == null)
        {
            return false;
        }
        else
        {
            return true;
        }
    }
    else
    {
        return lhs.CompareTo(rhs) < 0;
    }
}

/// <summary>Greater than comparison operator.</summary>
/// <param name="lhs">The left hand side.</param>
/// <param name="rhs">The right hand side.</param>
/// <returns>True if <paramref name="lhs"/> is greater than <paramref name="rhs"/>; otherwise, false.</returns>
public static bool operator >(T lhs, T rhs)
{
    return rhs < lhs;
}

/// <summary>Less than or equal comparison operator.</summary>
/// <param name="lhs">The left hand side.</param>
/// <param name="rhs">The right hand side.</param>
/// <returns>True if <paramref name="lhs"/> is less` than or equal to <paramref name="rhs"/>; otherwise, false.</returns>
public static bool operator <=(T lhs, T rhs)
{
    return !(rhs < lhs);
}

/// <summary>Greater than or equal comparison operator.</summary>
/// <param name="lhs">The left hand side.</param>
/// <param name="rhs">The right hand side.</param>
/// <returns>True if <paramref name="lhs"/> is greater than or equal to <paramref name="rhs"/>; otherwise, false.</returns>
public static bool operator >=(T lhs, T rhs)
{
    return !(lhs < rhs);
}

这是大量重复的代码。是否有一些方法可以创建一个抽象类或其他东西(例如 C++'s std::rel_ops),这样可以更容易地实现这些?

4

1 回答 1

1

有一种方法,但我不确定我会建议它。在示例中,为了简洁起见,我只定义了两个运算符。在其中一个中,我将实例转换为TemplateComparable<T>to,T因为在类约束中,T必须确实继承自TemplateComparable<T>并且转换将是有效的。

abstract class TemplateComparable<T> where T : TemplateComparable<T>, IComparable<T>
{
    public static bool operator ==(TemplateComparable<T> lhs, T rhs)
    {
        if (ReferenceEquals(lhs, null))
        {
            return ReferenceEquals(rhs, null);
        }
        return rhs.CompareTo(lhs as T) == 0;
    }

    public static bool operator !=(TemplateComparable<T> lhs, T rhs)
    {
        return !(lhs == rhs);
    }
}

class Foo : TemplateComparable<Foo>, IComparable<Foo>
{
    public int CompareTo(Foo other)
    {
        //Write your comparison code
        return 0;
    }
}

示例用法:

var v1 = new Foo();
var v2 = new Foo();
var equals = v1 == v2; //equals will be true

TemplateComparable<T>实现IComparable<T>Foo覆盖其成员的替代方法:

abstract class TemplateComparable<T> : IComparable<T> where T : TemplateComparable<T>
{
    public abstract int CompareTo(T other);

    public static bool operator ==(TemplateComparable<T> lhs, T rhs)
    {
        if (ReferenceEquals(lhs, null))
        {
            return ReferenceEquals(rhs, null);
        }
        return rhs.CompareTo(lhs as T) == 0;
    }

    public static bool operator !=(TemplateComparable<T> lhs, T rhs)
    {
        return !(lhs == rhs);
    }
}

class Foo : TemplateComparable<Foo>
{
    public override int CompareTo(Foo other)
    {
        //Write your comparation code
        return 0;
    }
}
于 2013-01-08T01:02:15.540 回答