如何在C#中通过引用传递值?

Dav*_*vid 1 c# linq pass-by-reference

我有以下linq代码.

searchResults = (from item1 in searchResults
              join item2 in coll
              on item1.skuID equals item2.Skuid
              where item2.SearchableValue == value
              select item1).ToList();
Run Code Online (Sandbox Code Playgroud)

变量searchResults作为通用List在方法中传递.上面的linq段过滤列表.当从方法返回时,我希望修改列表但引用在传入时保持不变.如何修改我的引用,而不是副本?谢谢.

ang*_*son 12

您应该返回过滤结果,因此如果您的方法如下所示:

public void Filter(List<Item> searchResults)
Run Code Online (Sandbox Code Playgroud)

将其更改为:

public IEnumerable<Item> Filter(List<Item> searchResults)
Run Code Online (Sandbox Code Playgroud)

然后返回结果而不是将其赋值给变量.换句话说,改变这个:

searchResults = (from item1 in searchResults
Run Code Online (Sandbox Code Playgroud)

对此:

return (from item1 in searchResults
Run Code Online (Sandbox Code Playgroud)

在您的通话中,请更改:

Filter(list)
Run Code Online (Sandbox Code Playgroud)

至:

list = Filter(list).ToList();
Run Code Online (Sandbox Code Playgroud)

这为您提供了最大的可重用性,因为您可以传入一个列表并信任该方法不要更改它,留下选择是将它放入一个新变量,还是替换原始列表,由您决定.

此外,正如Fredrik在他的评论中指出的.ToList()那样,Linq查询中的调用也应该被删除,并且您可能希望将输入参数更改为IEnumerable.

让我总结一下.

如果您有这样的代码:

public void Filter(List<Item> searchResults)
{
    searchResults = (from item1 in searchResults
                     join item2 in coll
                     on item1.skuID equals item2.Skuid
                     where item2.SearchableValue == value
                     select item1).ToList();
}

...
list = ...
Filter(list);
Run Code Online (Sandbox Code Playgroud)

并希望list更新,我将代码更改为:

       __ changed ______        __ changed ______
public IEnumerable<Item> Filter(IEnumerable<Item> searchResults)
{
    return from item1 in searchResults               <-- changed
           join item2 in coll
           on item1.skuID equals item2.Skuid
           where item2.SearchableValue == value
           select item1;                             <-- changed
}

...
list = ...         _ added__
list = Filter(list).ToList();
Run Code Online (Sandbox Code Playgroud)

  • +1 - 这绝对是*我最喜欢的解决方案(尽管我可能会将输入参数更改为`IEnumerable <Item>`而不是).另外,可以删除原始代码示例中的`.ToList()`调用. (2认同)

Eri*_*ert 7

我看到你已经得到了你的问题的答案.但是你可能会好奇为什么你不能在查询理解中使用ref参数.

原因是因为查询理解表达式表示查询,而不是结果.它表示查询的延迟执行.所以,假设我们允许:

IEnumerable<int> Frob(ref int x)
{  return from foo in whatever where foo.bar == x select foo.bar; }

IEnumerable<int> Blob()
{ 
    int y = 123; 
    var r = Frob(ref y);    
    y = 456;
    return r;
}
void Grob()
{
    foreach(int z in Blob()) { ... }
}
Run Code Online (Sandbox Code Playgroud)

这是做什么的?直到Blob返回后才执行查询,但查询引用不再存在的帧上的局部变量引用.

每次在查询中使用ref时,编译器都无法知道您处于这种情况,因此它完全禁止它.