-5

假设我有一个方法用一些参数调用另一个方法,如下所示:

   public void SomeMethod()
   {
      List<SomeObject> TheList = SomeQueryThatReturnsTheList();

      TheList = DoSomeWorkWithList(TheList);
   }

   public List<SomeObject> WorkForList(List<SomeObject> TheListAsParameter)
   {
      foreach (SomeObject x in TheListAsParameter)
      {
          ....
      }

      return TheListAsParameter;
   }

如您所见,该方法WorkForList返回它收到的列表。我的问题是:如果我不返回列表并public void WorkForList(List<SomeObject> TheListAsParameter)按照 c# 中的引用传递的方式重写签名,是否意味着 TheList inSomeMethod将使用WorkForList方法中完成的工作进行更新?如果是这样,以下代码是否会相同:

   public void SomeMethod()
   {
      List<SomeObject> TheList = SomeQueryThatReturnsTheList();

      DoSomeWorkWithList(TheList);
   }

   public void WorkForList(List<SomeObject> TheListAsParameter)
   {
        ....
   }

谢谢。

4

6 回答 6

4

好吧,如果你不使用ref关键字,它的地址将通过值传递,这意味着你可以改变它的元素,但你不能初始化它或者不能将它赋值为 null。例如。如果在你的方法中你这样做:

public void WorkForList(List<SomeObject> TheListAsParameter)
{
  TheListAsParameter = null;
} 

您将看不到调用者的差异。

您应该看到这篇文章:Jon Skeet 的 C# 中的参数传递

于 2013-02-11T12:55:01.170 回答
2

在这种情况下,代码将执行您想要执行的操作,请记住两件事:

  • C# 是“按值传递”语言。它传递对象的地址,因此仅在您使用此实例时才有效,而不是更改实例本身。为此,您应该使用ref关键字,但这通常会导致代码更难阅读。
  • 返回对象极大地提高了可读性 - 你所做的被认为是副作用,你的方法的用户(可能是另一个团队成员)可能不知道你正在修改列表内容。
于 2013-02-11T12:57:21.130 回答
1

是的,你可以这么做。但是返回对象可能是有用的,为了清楚起见,并允许方法链接。

例如,使用您的第WorkForList一种方法:

yourObject.WorkForList(list).DoSomethingWithTheReturnedList();
于 2013-02-11T12:53:58.423 回答
1

是的 - 这应该和你描述的完全一样......你当然可以测试你已经编写的代码吗?

于 2013-02-11T12:54:33.283 回答
1

是的,只要您的WorkForList()方法没有这样的行:

TheListAsParameter = something;

那么您所做的任何更改都TheListAsParameter将反映在调用方法中而不返回它。

在这里准确地说,在这种情况下,您不是通过引用传递变量。您正在按值传递引用类型。通过引用传递涉及到refC# 中关键字的使用。

于 2013-02-11T12:56:14.467 回答
1

只要您不使用 foreach 来修改列表的值:

  foreach (SomeObject x in TheListAsParameter)
  {
      ....
  }

由于不允许您使用 foreach 修改您正在浏览的 Collection 的内容。

于 2013-02-11T13:01:01.260 回答