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

C# 如何将两个重载重构为一个重载,c#,generics,refactoring,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) {} private static bool Co

我偶然发现了两个完全相同的重载方法,我想将其重构为一个

    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)
    {}
private static bool Compare(T obj1,T obj2,out int test),其中T:i可比较
{}
专用静态布尔比较(IComparable obj1、IComparable obj2、out int测试)
{}

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

注释是正确的,因为
IComparable
IComparable
是不同的接口,所以这两种方法是不同的

但是,考虑到以下情况,仍然需要注意:

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) { }

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

注释是正确的,因为这两种方法不同,因为
IComparable
IComparable
是不同的接口

但是,考虑到以下情况,仍然需要注意:

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) { }

(*)严格来说不正确,隐式转换在这里起作用。

正如@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;
    }
static bool CompareT(T obj1,T obj2,out int test),其中T:IComparable=>
比较(obj1,obj2,()=>obj1。比较到(obj2),输出测试);
静态布尔比较(IComparable obj1、IComparable obj2、out int test)=>
比较(obj1,obj2,()=>obj1。比较到(obj2),输出测试);
静态布尔比较(对象obj1、对象obj2、函数f、out int测试)
{
if(参考等于(obj1,obj2))
{
测试=0;
返回true;
}
如果(obj1==null)
{
测试=1;
返回false;
}
test=f();
如果(test==0)返回true;
返回false;
}
我把正文放在这里只是为了参考,看看f参数的用法。在原始方法中,它的调用是CompareTo调用。
感谢所有的评论者澄清为什么简化为单个签名是不可行的。

正如@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;
    }
static bool CompareT(T obj1,T obj2,out int test),其中T:IComparable=>
比较(obj1,obj2,()=>obj1。比较到(obj2),输出测试);
静态布尔比较(IComparable obj1、IComparable obj2、out int test)=>
比较(obj1,obj2,()=>obj1。比较到(obj2),输出测试);
静态布尔比较(对象obj1、对象obj2、函数f、out int测试)
{
if(参考等于(obj1,obj2))
{
测试=0;
返回true;
}
如果(obj1==null)
{
测试=1;
返回false;
}
test=f();
如果(test==0)返回true;
返回false;
}
我把正文放在这里只是为了参考,看看f参数的用法。在原始方法中,它的调用是CompareTo调用。
感谢所有的评论者澄清为什么简化为一个签名是不可行的。

您是否尝试过删除一个签名,看看有什么中断?如果没有看到“idenitcal code”,就无法猜测如何重构它。但我想您可以尝试将非泛型版本中使用的对象强制转换为泛型类型参数并调用该参数,例如,
Compare((MyType)obj1,(MyType)obj1,out test)
。我在这里遇到了困难,但您可能会将大部分代码重构为第三个私有方法,并在不同的比较和比较方法中仅保留特定于接口的
IComparable.CompareTo
IComparable.CompareTo
调用…@elgonzo Sound advice。我就是这么做的,虽然没有完全达到我想要的,但至少没有重复的代码。我不认为这些方法中的代码数量会很多,因为其中一个是泛型的,你说它们有相同的主体。既然我们已经确定这两个接口是不兼容的,那么保留这两个方法真的很重要吗?你是否尝试过删除其中一个,看看会有什么中断?如果没有看到“idenitcal代码”,就无法猜测如何重构它。但我想您可以尝试将非泛型版本中使用的对象强制转换为泛型类型参数并调用该参数,例如,
Compare((MyType)obj1,(MyType)obj1,out test)
。我在这里遇到了困难,但您可能会将大部分代码重构为第三个私有方法,并在不同的比较和比较方法中仅保留特定于接口的
IComparable.CompareTo
IComparable.CompareTo
调用…@elgonzo Sound advice。我就是这么做的,虽然没有完全达到我想要的,但至少没有重复的代码。我不认为这些方法中的代码数量会很多,因为其中一个是泛型的,你说它们有相同的主体。既然我们已经确定这两个接口是不兼容的,那么保留这两个方法真的重要吗?