什么是避免重复此代码的最佳方法

时间:2011-07-29 10:12:14

标签: c# refactoring

我有以下方法:

    public  int CountProperty1
    {
        get
        {
            int count = 0;
            foreach (var row in Data)
            {
                count = count + row.Property1;
            }
            return count ;
        }
    }

    public  int CountProperty2
    {
        get
        {
            int count = 0;
            foreach (var row in Data)
            {
                count = count + row.Property2;
            }
            return count ;
        }
    }

避免重复的最佳方法是什么,尽可能多地共享代码

7 个答案:

答案 0 :(得分:10)

如何使用LINQ和Sum扩展方法?

public int CountProperty1 
{
    get { return Data.Sum(r => r.Property1); }
} 

如果不是一个选项,你可以将逻辑重构为你自己的sum方法:

public  int CountProperty1
{
    get
    {
        return CountProperty(r => r.Property1);
    }
}

public  int CountProperty2
{
    get
    {
        return CountProperty(r => r.Property2);
    }
}

private int CountProperty(Func<Row,int> countSelector)
{
     int count = 0;
     foreach (var row in Data)
     {
         count = count + countSelector(row);
     }
     return count ;
}

注意最后一个例子:我编写了“Row”类型,因为从你的例子中看不出来。替换为适当的类型。

答案 1 :(得分:2)

不要打扰。

您可以缩短代码,但如果您尝试重构代码以消除重复,那么您只会使代码更复杂。

将重构工作集中在更复杂,更有价值的案例上。生命太短了......

几个字节的磁盘空间极其便宜,而Copy / Paste是开发人员最好的朋友。此外,如果我们对此纯粹主义,请考虑重构的运行时开销。

答案 2 :(得分:2)

可能不是您正在寻找的答案,但这不一定是重复。有时会产生误解,如果两个不同的函数发生相同,则应重构它们以删除副本。以我的拙见,这是错的。

如果它们是真正的复制和识别或接近相同的概念,那么它只是重复的。因为它是重复的(至少应该删除重复),它不仅仅是因为它们碰巧使用相同的代码,而是出于同样的原因使用相同的代码。

可能只是因为您发布的样本,但它很简单。尽管两个属性的实现是相同的,但必须有一些有效的商业原因,你有这两个属性,否则最简单的答案是一起删除第二个属性。但是,如果你真的有两个属性,而它们现在看起来恰好相同,那并不意味着它们将来在功能上不会分歧(这没关系)。

这个想法是为了最大限度地降低复杂性和维护成本。只有当你的代码有意义并模拟现实时,你才能做到这一点,但如果它通过将看似相似的东西混为一谈而引入错误的比较,那就不行了。

http://mooneyblog.mmdbsolutions.com/index.php/2010/07/30/reusable-code-is-bad/

答案 3 :(得分:1)

我不会亲自打扰属性,只需使用linq直接调用外部

myObject.Data.Sum(x=>x.Property1)

答案 4 :(得分:0)

这很干净。如果我知道行的类型,我倾向于将PropertyN()放入其类而不是这里,但缺乏这些知识:

public int CountPropertyN(int n)
{
    int count = 0;
    foreach (var row in Data)
    {
        count = count + PropertyN(row, n)
    }
    return count ;
}

private int PropertyN(var row, int n) 
{
     if (n == 1) return row.Property1;
     else return row.Property2;
}

答案 5 :(得分:-2)

给它一个输入参数,说明哪个参数

public  int CountProperty (int whichProperty) 
    {
        get
        {
            int count = 0;
            foreach (var row in Data)
            {
                if( whichProperty = 1)
                    count = count + row.Property1;
                if( whichProperty = 2)
                    count = count + row.Property2;
            }
            return count ;
        }
    }

答案 6 :(得分:-2)

public  int CountProperty1
{
    get
    {
        return GetCount(row.Property1);
    }
}

public  int CountProperty2
{
    get
    {
        return GetCount(row.Property2);
    }
}

private int GetCount(object property)
{
    int count = 0;
    foreach (var row in Data)
    {
        if(property == row.Property1)
        {
            count = count + row.Property1;
        }
        else if (property == row.Property2)
        {
            count = count + row.Property2;
        }
    }
    return count ;
}

在私有方法中我在签名中使用了对象 - 直到我对属性所需的类型有了更好的了解