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

C# 如何在C中通过引用传递值?,c#,linq,pass-by-reference,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(); 变量searchResults作为泛型列表传递

我有以下linq代码

searchResults = (from item1 in searchResults
              join item2 in coll
              on item1.skuID equals item2.Skuid
              where item2.SearchableValue == value
              select item1).ToList();
变量searchResults作为泛型列表传递到方法中。上面的linq段过滤列表。当从方法返回时,我希望列表会被修改,但是引用在传入时保持不变。我如何实现修改我的参考,而不是副本?谢谢。

您正在将searchResults参数指定给一个新的列表实例

要查看调用方法中的更改,需要将其设置为ref参数

var results = (from item1 in searchResults
               join item2 in coll
               on item1.skuID equals item2.Skuid
               where item2.SearchableValue == value
               select item1).ToList();

searchResults.Clear();
searchResults.AddRange(results);
或者,您可以就地修改列表,如下所示:

var newResults = (from item1 in searchResults
                  join item2 in coll
                  on item1.skuID equals item2.Skuid
                  where item2.SearchableValue == value
                  select item1).ToArray();

searchResults.Clear();
searchResults.AddRange(newResults);
public void Filter(List<Item> searchResults)
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);
您正在将searchResults参数指定给一个新的列表实例

要查看调用方法中的更改,需要将其设置为ref参数

var results = (from item1 in searchResults
               join item2 in coll
               on item1.skuID equals item2.Skuid
               where item2.SearchableValue == value
               select item1).ToList();

searchResults.Clear();
searchResults.AddRange(results);
或者,您可以就地修改列表,如下所示:

var newResults = (from item1 in searchResults
                  join item2 in coll
                  on item1.skuID equals item2.Skuid
                  where item2.SearchableValue == value
                  select item1).ToArray();

searchResults.Clear();
searchResults.AddRange(newResults);
public void Filter(List<Item> searchResults)
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);
您需要将searchResults参数标记为ref

看起来SLaks更快地找到了这个答案。

您需要将searchResults参数标记为ref

SLaks似乎更快地找到了这个答案。

变量searchResults需要作为[ref][1]参数传入

var results = (from item1 in searchResults
               join item2 in coll
               on item1.skuID equals item2.Skuid
               where item2.SearchableValue == value
               select item1).ToList();

searchResults.Clear();
searchResults.AddRange(results);
方法签名如下所示

//Note you only need to ref the one variable.
void filter(ref List searchResults, object otherParameter)
{
   //LINQ and stuff here
}
要调用它,还需要使用ref:

变量searchResults需要作为[ref][1]参数传入

var results = (from item1 in searchResults
               join item2 in coll
               on item1.skuID equals item2.Skuid
               where item2.SearchableValue == value
               select item1).ToList();

searchResults.Clear();
searchResults.AddRange(results);
方法签名如下所示

//Note you only need to ref the one variable.
void filter(ref List searchResults, object otherParameter)
{
   //LINQ and stuff here
}
要调用它,还需要使用ref:


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

var newResults = (from item1 in searchResults
                  join item2 in coll
                  on item1.skuID equals item2.Skuid
                  where item2.SearchableValue == value
                  select item1).ToArray();

searchResults.Clear();
searchResults.AddRange(newResults);
public void Filter(List<Item> searchResults)
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);
为此:

return (from item1 in searchResults
在您的通话中,更改为:

Filter(list)
致:

这为您提供了最大的可重用性,因为您可以传入一个列表,并相信该方法不会对其进行更改,是将其放入新变量中,还是替换原始列表,由您自己选择

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

让我总结一下

如果您有这样的代码:

var newResults = (from item1 in searchResults
                  join item2 in coll
                  on item1.skuID equals item2.Skuid
                  where item2.SearchableValue == value
                  select item1).ToArray();

searchResults.Clear();
searchResults.AddRange(newResults);
public void Filter(List<Item> searchResults)
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);

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

var newResults = (from item1 in searchResults
                  join item2 in coll
                  on item1.skuID equals item2.Skuid
                  where item2.SearchableValue == value
                  select item1).ToArray();

searchResults.Clear();
searchResults.AddRange(newResults);
public void Filter(List<Item> searchResults)
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);
为此:

return (from item1 in searchResults
在您的通话中,更改为:

Filter(list)
致:

这为您提供了最大的可重用性,因为您可以传入一个列表,并相信该方法不会对其进行更改,是将其放入新变量中,还是替换原始列表,由您自己选择

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

让我总结一下

如果您有这样的代码:

var newResults = (from item1 in searchResults
                  join item2 in coll
                  on item1.skuID equals item2.Skuid
                  where item2.SearchableValue == value
                  select item1).ToArray();

searchResults.Clear();
searchResults.AddRange(newResults);
public void Filter(List<Item> searchResults)
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);

我看你的问题已经有答案了。但您可能会好奇为什么不能在查询理解中使用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()) { ... }
}
这有什么用?直到Blob返回后才执行查询,但查询引用的是不再存在的帧上的局部变量引用


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

我知道您已经得到了问题的答案。但您可能会好奇为什么不能在查询理解中使用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()) { ... }
}
这有什么用?直到Blob返回后才执行查询,但查询引用的是不再存在的帧上的局部变量引用


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

我尝试过,但出现错误CS1628:无法在匿名方法、lambda表达式或查询表达式中使用ref或out参数“searchResults”。。。添加ref没有任何作用。列表默认作为引用传入。@威尔:否,对列表的引用是按值传入的,这是非常不同的!方法内部的引用已更改。@Hans:虽然您对列表的引用按值传递是正确的,但答案中的代码示例不会更改引用,因此ref关键字实际上没有添加任何内容。引用的具体更改位置?我已尝试,但出现错误CS1628:无法在匿名方法、lambda表达式或查询表达式中使用ref或out参数“searchResults”。。。添加ref没有任何作用。列表默认作为引用传入。@威尔:否,对列表的引用是按值传入的,这是非常不同的!方法内部的引用已更改。@Hans:虽然您对通过值传递的列表的引用是正确的,但代码
答案中的示例不会更改引用,因此ref关键字不会真正添加任何内容。引用的具体更改位置?+1-这肯定是我首选的解决方案,尽管我可能会将输入参数改为IEnumerable。此外,可以删除原始代码示例中的.ToList调用。+1-这肯定是我首选的解决方案,尽管我可能会将输入参数改为IEnumerable。此外,可以删除原始代码示例中的.ToList调用。