使用几乎相同的内容重构两个方法

时间:2010-07-19 15:35:08

标签: c# refactoring

我有两种方法具有几乎相同的内容:

public string Method1(int someInt)
{
    if(someBoolean)
        return "test";

    if(someOtherBoolean)
    {
        return "dfjakdsad";
    }
    else
    {
        string myStr = getString(someInt)
    }
}

 public string Method2(myEnum myenum)
 {
    if(someBoolean)
        return "test";

    if(someOtherBoolean)
    {
        return "dfjakdsad";
    }
    else
    {
        string myStr = getString(myenum)
    }
 }

区别在于elsestring myStr = getString

中的方法签名和单个陈述

从许多地方调用Method1,因此它必须以某种方式保留。我该怎么重构呢?

6 个答案:

答案 0 :(得分:5)

如果您的枚举可以转换为int,并假设您的getString返回枚举的数值而不是文本,那么只需:

public string Method2(myEnum myenum) 
 { 
    return Method1((int)myenum);
 } 

作为一个有趣的方面 - 我已经看到这种情况创造了“相同的空白,不同的价值观”。

另外有趣的是 - 我的基于头部的编译器说代码实际上不会编译: - )

我不担心重构这一点 - 增益略高于代码可读性,如果发生变化,可能会降低变更的复杂性 - 但这并不是复杂的代码,因此额外的测试开销如果它被大量使用可能会增加收益。

更新:如果enum getString返回文本,即“Foo”,那么就不能以我所描述的方式重构此代码。

答案 1 :(得分:5)

我建议使用通用:

public string Method<T>(T arg)
{
    if(someBoolen)
        return "test";

    if(someOtherBoolean)
    {
        return "dfjakdsad";
    }
    else
    {
        string myStr = getString(arg)
    }
}

这假定getString本身是通用的,或者可以处理任何类型的对象。

答案 2 :(得分:4)

您可以传递Func作为第二个参数

public string Method(Func<string> myFunc)
{
    if(someBoolen)
        return "test";

    if(someOtherBoolean)
    {
        return "dfjakdsad";
    }
    else
    {
        string myStr = myFunc();
    }
}

Method(myEnum => getString(myEnum));
Method(someInt => getString(someInt));

如果你总是按照JSBangs的说法调用getString,那么泛型是最好的解决方案。

答案 3 :(得分:3)

有问题的代码是否有效,经过测试的代码?如果是这样,在没有充分理由的情况下不会更改。我会问自己两个问题:

1)是否使代码缩短了几行,而且多余的冗余真的值得意外引入错误的风险?

2)这是代码中我的有限时间,精力和技能可以最佳应用的地方吗?

如果这是您的代码中最严重的问题,那么恭喜您,您有 awesome 代码。我会在其他地方寻找更大的鱼来煎炸。

答案 4 :(得分:0)

是否会在您的场景中转换枚举并调用函数的int版本?

public string Method(myEnum myenum)
{
    return Method((int)myenum);
}

public string Method(int someInt) {
    if(someBoolen)
        return "test";

    if(someOtherBoolean)
    {
        return "dfjakdsad";
    }
    else
    {
        string myStr = getString(someInt)
    }
}

答案 5 :(得分:0)

我会提出亚当答案的反面:

枚举是强类型的,而int则不是 - 所以你应该尽可能地使用枚举。因此,我希望“真实”方法需要enum作为参数,并且重载接受int并将其强制转换为enum

请注意,两个方法共享相同的名称,首先放置枚举:这意味着intellisense将首先“建议”枚举方法,但将int显示为可用选项

public string Method1(myEnum myenum)
{
    if(someBoolen)
        return "test";

    if(someOtherBoolean)
    {
        return "dfjakdsad";
    }
    else
    {
        string myStr = getString(myenum)
    }
 }

public string Method1(int someInt)
{
    return Method1((myEnum) someInt);
}

更新:正如亚当所问,此解决方案确实暗示您将始终传递int,该enum对应于int的成员。根据我的经验,我这是常见的做法(如果枚举只映射到有效{{1}}的子集,那么枚举提供了什么价值?) - 但是值得确保它适合您的用例。

相关问题