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

C# 如果方法对引用类型执行操作,是否需要返回它?,c#,C#,如果我有一个方法专门对引用类型变量(例如datatable)进行操作并对其进行修改,是否需要从该方法返回该变量 例如,以下方法遍历datatable并修剪其中的所有值,然后将datatable返回给调用方: private DataTable TrimAllDataInDataTable(DataTable dt) { foreach (DataRow row in dt.Rows) {

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

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

        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会更好吗?返回它似乎毫无意义(?),但您是否认为在对其进行操作后返回对象(就像现在一样)会读得更好?

如果不使用返回值,我会丢失它。如果要忽略引用,那么将引用复制回调用帧就没有必要浪费周期。但也许在这个函数中可以执行一些错误检查?在这种情况下,您可能返回真/假“成功”代码。

对于DataTable或函数本身,从函数返回更改的引用变量没有任何值

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

它是多余的

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

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

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

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

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

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

      DataTable dt = GetDataTable();
      int rowCount = TrimAllDataInDataTable(dt).Rows.Count; // OK, perhaps not the  
                                                            // best example, but it  
                                                            // shows the idea
      
      您还可以使用它嵌套方法调用:

      SomeMethodThatTakesADataTable(TrimAllDataInDataTable(dt));
      

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

      一个问题:这个方法没有成为
      DataTable
      类成员的原因吗?
      我认为
      DataTable.TrimAllData()
      会更好地工作我想到了链接。例如,假设您有三种方法A、B和C。而不是调用:

      对象A(对象)

      对象B(对象)

      对象C(对象); 你可以说得简明扼要:

      对象.A(对象).B(对象).C(对象);


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

      就我个人而言,我会返回void。方法名称让开发人员知道您将修改DataTable中的值,返回DataTable不会带来任何好处,同时它可能会引入模糊性,即您在处理表之前克隆表。

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

      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();
                  }
              }
          }
      
          ...
      }
      

      +1对于建议将其作为DataTable类的扩展方法,起初我认为您的意思是“创建一个继承自DataTable的新类”,这可能是“最佳实践”但是我会避免这样做,因为涉及到额外的代码行。我还没有使用扩展方法,所以这可能是一个查看它们的好机会…如果修改原始对象,这是一个非常糟糕的主意。没有一个Linq操作符可以这样做。另一方面,StringBuilder可以这样做,因此您可以使用sb.Append(X).Append(y).AppendLine(z);TrimAllDataInDataTable不是访问器或纯函数,也不是fluent界面中的生成器方法,因此返回“链接”参数是个坏主意。如果它是对象,则复制回帧的操作可以忽略不计。这更像是“最佳实践”的问题。