C# 如果方法对引用类型执行操作,是否需要返回它?
如果我有一个方法专门对引用类型变量(例如datatable)进行操作并对其进行修改,是否需要从该方法返回该变量 例如,以下方法遍历datatable并修剪其中的所有值,然后将datatable返回给调用方:C# 如果方法对引用类型执行操作,是否需要返回它?,c#,C#,如果我有一个方法专门对引用类型变量(例如datatable)进行操作并对其进行修改,是否需要从该方法返回该变量 例如,以下方法遍历datatable并修剪其中的所有值,然后将datatable返回给调用方: private DataTable TrimAllDataInDataTable(DataTable dt) { foreach (DataRow row in dt.Rows) {
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界面中的生成器方法,因此返回“链接”参数是个坏主意。如果它是对象,则复制回帧的操作可以忽略不计。这更像是“最佳实践”的问题。