不能在匿名方法中使用ref或out参数[重复]

时间:2021-01-17 21:03:48

This question already has an answer here:

这个问题在这里已有答案:

I have a problem with my code in c# if someone could help resolve my problem.

如果有人可以帮我解决问题,我在c#中的代码有问题。

In a function I am parsing a Xml file and saving it to a struct.

在函数中,我正在解析Xml文件并将其保存到结构中。

Then I try to retreive some info from said struct with a specific node id and my code fails with

然后我尝试从具有特定节点ID的所述结构中检索一些信息,并且我的代码失败了

"Cannot use ref or out parameter 'c' inside an anonymous method, lambda expression, or query expression"

“不能在匿名方法,lambda表达式或查询表达式中使用ref或out参数'c'”

Here is my code:

这是我的代码:

public void XmlParser(ref Point a, ref Point b, ref Point c)
{
     XDocument xdoc = XDocument.Load(XmlDirPath); 
     var coordinates = from r in xdoc.Descendants("move")
                        where int.Parse(r.Attribute("id").Value) == c.NodeID  // !! here is the error !!
                        select new
                        {
                              X = r.Element("x").Value,
                              Y = r.Element("y").Value,
                              Z = r.Element("z").Value, 
                              nID = r.Attribute("id").Value
                         };

     foreach (var r in coordinates)
     {
          c.x = float.Parse(r.X1, CultureInfo.InvariantCulture);
          c.y = float.Parse(r.Y1, CultureInfo.InvariantCulture);
          c.z = float.Parse(r.Z1, CultureInfo.InvariantCulture);
          c.NodeID = Convert.ToInt16(r.nID);
     }
}

public struct Point
{
    public  float x;
    public  float y;
    public  float z;
    public  int   NodeID;
}

3 个解决方案

#1


7  

Well, you're not allowed to use a ref or a out parameter in an anonymous method or a lambda, just as the compiler error says.

好吧,你不允许在匿名方法或lambda中使用ref或out参数,正如编译器错误所说的那样。

Instead you have to copy the value out of the ref parameter into a local variable and use that:

相反,您必须将ref参数中的值复制到局部变量中并使用:

var nodeId = c.NodeID;
var coordinates = from r in xdoc.Descendants("move")
    where int.Parse(r.Attribute("id").Value) == nodeId
    ...

#2


3  

As suggested in other answers you have to copy the ref variable locally in your method. The reason why you have to do it is because lambdas/linq queries change the lifetime of variables that they capture causing the parameters to live longer than the current method frame as the value can be accessed after the method frame is no longer on the stack.

如其他答案所示,您必须在方法中本地复制ref变量。你必须这样做的原因是因为lambdas / linq查询改变了它们捕获的变量的生命周期,导致参数比当前方法帧更长寿,因为在方法帧不再在堆栈上之后可以访问该值。

There is an interesting answer here that explains carefully why you can't use ref/out parameters in anonymous methods.

这里有一个有趣的答案,它解释了为什么你不能在匿名方法中使用ref / out参数。

#3


2  

You should pull the retrieval of the ID out of the anonymous method:

您应该从匿名方法中提取ID的检索:

var nodeId = c.NodeID;

var coordinates = from r in xdoc.Descendants("move")
                           where int.Parse(r.Attribute("id").Value) == nodeId

#1


7  

Well, you're not allowed to use a ref or a out parameter in an anonymous method or a lambda, just as the compiler error says.

好吧,你不允许在匿名方法或lambda中使用ref或out参数,正如编译器错误所说的那样。

Instead you have to copy the value out of the ref parameter into a local variable and use that:

相反,您必须将ref参数中的值复制到局部变量中并使用:

var nodeId = c.NodeID;
var coordinates = from r in xdoc.Descendants("move")
    where int.Parse(r.Attribute("id").Value) == nodeId
    ...

#2


3  

As suggested in other answers you have to copy the ref variable locally in your method. The reason why you have to do it is because lambdas/linq queries change the lifetime of variables that they capture causing the parameters to live longer than the current method frame as the value can be accessed after the method frame is no longer on the stack.

如其他答案所示,您必须在方法中本地复制ref变量。你必须这样做的原因是因为lambdas / linq查询改变了它们捕获的变量的生命周期,导致参数比当前方法帧更长寿,因为在方法帧不再在堆栈上之后可以访问该值。

There is an interesting answer here that explains carefully why you can't use ref/out parameters in anonymous methods.

这里有一个有趣的答案,它解释了为什么你不能在匿名方法中使用ref / out参数。

#3


2  

You should pull the retrieval of the ID out of the anonymous method:

您应该从匿名方法中提取ID的检索:

var nodeId = c.NodeID;

var coordinates = from r in xdoc.Descendants("move")
                           where int.Parse(r.Attribute("id").Value) == nodeId