通过引用传递而不返回值

时间:2013-02-11 12:52:29

标签: c#

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

   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#中通过引用传递意味着SomeMethod中的TheList将使用已完成的工作进行更新在WorkForList方法?如果是这样,以下代码将是相同的:

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

      DoSomeWorkWithList(TheList);
   }

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

感谢。

6 个答案:

答案 0 :(得分:4)

如果您不使用ref关键字,其地址将按值传递,意味着您可以更改其元素,但无法初始化或者不能将其指定为null。例如。如果在您的方法中,您可以:

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

您不会看到来电者的不同之处。

您应该看到这篇文章:Parameter passing in C# by Jon Skeet

答案 1 :(得分:2)

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

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

答案 2 :(得分:1)

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

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

yourObject.WorkForList(list).DoSomethingWithTheReturnedList();

答案 3 :(得分:1)

是的 - 这应该与您所描述的完全相同......当然您可以只测试您已编写的代码吗?

答案 4 :(得分:1)

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

TheListAsParameter = something;

然后,您对TheListAsParameter所做的任何更改都将反映在调用方法中,而不会返回它。

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

答案 5 :(得分:1)

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

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

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