如何将两个重载重构为一个

时间:2018-10-28 20:26:22

标签: c# generics refactoring

我偶然发现了两种方法,它们具有完全相同的主体,并且我希望将其重构为单个。

    private static bool Compare<T>(T obj1, T obj2, out int test) where T : IComparable<T>
    {}

    private static bool Compare(IComparable obj1, IComparable obj2, out int test)
    {}

签名表示几乎相同的东西,唯一的区别是泛型。有没有办法合并它们?

2 个答案:

答案 0 :(得分:5)

到目前为止,由于ObjectIComparable是不同的接口,两种方法都不相同,因此注释是正确的。

但在以下情况下,它仍然指示要注意:

IComparable<T>

如果将代码重构为一个重载,则将执行重大更改。这两个重载绝对是相同。

在通用重载中,private static bool Compare<T>( T obj1, T obj2, out int test) where T : IComparable { } private static bool Compare( IComparable obj1, IComparable obj2, out int test) { } obj1必须是相同的编译时间类型(*)。在第二次重载中,obj2obj1可以是不同类型,只要它们实现obj2

IComparable

(*)并非完全正确,隐式转换在这里起作用。

答案 1 :(得分:0)

正如@elgonzo所建议的那样,我通过将其重构为第三种方法来摆脱了重复的正文。

    static bool CompareT<T>(T obj1, T obj2, out int test) where T : IComparable<T> =>
        Compare(obj1, obj2, () => obj1.CompareTo(obj2), out test);

    static bool Compare(IComparable obj1, IComparable obj2, out int test) =>
        Compare(obj1, obj2, () => obj1.CompareTo(obj2), out test);

    static bool Compare(object obj1, object obj2, Func<int> f, out int test)
    {
        if (ReferenceEquals(obj1, obj2))
        {
            test = 0;
            return true;
        }

        if (obj1 == null)
        {
            test = 1;
            return false;
        }

        test = f();

        if (test == 0) return true;
        return false;
    }

我在此处包括正文仅供参考,以了解 f 参数的用法。在原始方法中,调用 CompareTo 代替了它。 感谢所有评论者澄清为什么减少单个签名的可行性。