如果方法对引用类型执行操作,是否需要返回它?

时间:2009-06-25 12:42:31

标签: c#

如果我有一个专门对引用类型变量(例如数据表)进行操作并修改它的方法,是否需要从方法中返回该变量?

例如,以下方法遍历数据表并修剪其中的所有值,然后将数据表返回给调用者:

        private DataTable TrimAllDataInDataTable(DataTable dt)
        {
            foreach (DataRow row in dt.Rows)
            {
                foreach (DataColumn dc in dt.Columns)
                {
                    row[dc] = row[dc].ToString().Trim();
                }
            }

            return dt;
        }

如果此方法返回void会更好吗?返回它(?)似乎没有意义,但是如果它在操作之后返回对象(就像现在那样),你认为它读得更好吗?

9 个答案:

答案 0 :(得分:9)

对我来说,当一个方法返回一个引用类型时,我希望它是一个新对象。我会选择让它返回无效。

一个问题:这个方法有没有理由不成为DataTable类的成员? 我认为DataTable.TrimAllData()会更好用

答案 1 :(得分:5)

就个人而言,我会回归无效。方法名称允许开发人员知道您将修改DataTable中的值,并且返回DataTable不会带来任何好处,同时它可能会引入您在处理表之前克隆表的歧义。

答案 2 :(得分:4)

如果您没有使用返回值,我会失去它。如果要忽略它,则浪费将引用复制回调用帧的循环没有用处。但也许你可以在这个函数中做一些错误检查?在这种情况下,您可能会返回一个真/假“成功”代码。

答案 3 :(得分:2)

这样做的一个原因是它允许你将方法串在一起:

TrimAllDataInDataTable(dt).WriteXml(...);

并不总是有用,甚至不合适,但有时可能很好。

答案 4 :(得分:1)

这是多余的。

有两种方法可以做到这一点 - 经典方式(调用者选择操作/更改的内容)和被调用者更改(这就是你所拥有的:

  • 如果调用者选择了要操作的内容,那么您的方法将在数据集的副本上运行,并返回该副本,保持原始状态不变。如果需要,调用者可以覆盖原始文件。
  • 替代方法让被调用的方法执行就地操作,在这种情况下,返回值通常是布尔值(“是的,我已成功!”)或包含受影响值的数量的int。

答案 5 :(得分:0)

出于DataTable或函数本身的目的,从函数返回已更改的引用变量没有任何价值。

但是,如果你喜欢函数式编程的工作方式(比如Linq扩展方法),那么返回DataTable是个好主意。它允许您链接对变量的调用,并为更具表现力的代码提供选项。

答案 6 :(得分:0)

通过返回对象可以添加的额外值是您可以以不同方式链接调用:

DataTable dt = GetDataTable();
int rowCount = TrimAllDataInDataTable(dt).Rows.Count; // OK, perhaps not the  
                                                      // best example, but it  
                                                      // shows the idea

您也可以使用它嵌套方法调用:

SomeMethodThatTakesADataTable(TrimAllDataInDataTable(dt));

答案 7 :(得分:0)

链接浮现在脑海中。例如,假设您有三个方法A,B和C.而不是调用:

object.A(object);

object.B(object);

object.C(object);

you could go for the terse:

object.A(object).B(object).C(object);

您可以使用null返回值来指示出现错误并捕获NullPointerException(或等效的,我不熟悉C#)以获取上述“链式”语句。

答案 8 :(得分:0)

作为输出的参数可能被认为是混乱的,因为更多的是,在OO编程中我们不希望将参数用作输入而不是输出。 Clean Code建议的另一种方法是将变量修改为类的成员:

class DataTableTrimmer {

    private DataTable dt;

    public DataTableTrimmer(DataTable pDt) {
        dt = pDt;
    }

    public void TrimAllDataInDataTable()
    {
        foreach (DataRow row in dt.Rows)
        {
            foreach (DataColumn dc in dt.Columns)
            {
                row[dc] = row[dc].ToString().Trim();
            }
        }
    }

    ...
}