C#:字符串参数被神秘地重置为空 - 请帮忙!
我正在尝试解析表达式树并编写了以下代码:
private void TestExpressionTree()
{
Expression<Func<int, bool>> expression = x => x == 1 || x == 2;
string output = String.Empty;
HandleExpression(expression.Body, output);
Output("Output", output);
}
private void HandleExpression(Expression expression, string output)
{
switch (expression.NodeType)
{
case ExpressionType.Conditional:
HandleConditionalExpression(expression, output);
break;
case ExpressionType.OrElse:
HandleOrElseExpression(expression, output);
break;
case ExpressionType.Equal:
HandleEqualExpression(expression, output);
break;
case ExpressionType.Parameter:
HandleParameterExpression(expression, output);
break;
case ExpressionType.Constant:
HandleConstantExpression(expression, output);
break;
}
}
private void HandleConditionalExpression(Expression expression, string output)
{
ConditionalExpression conditionalExpression = (ConditionalExpression) expression;
HandleExpression(conditionalExpression.Test, output);
}
private void HandleOrElseExpression(Expression expression, string output)
{
BinaryExpression binaryExpression = (BinaryExpression)expression;
HandleExpression(binaryExpression.Left, output);
output += "||";
HandleExpression(binaryExpression.Right, output);
}
private void HandleEqualExpression(Expression expression, string output)
{
BinaryExpression binaryExpression = (BinaryExpression)expression;
HandleExpression(binaryExpression.Left, output);
output += "=";
HandleExpression(binaryExpression.Right, output);
}
private void HandleParameterExpression(Expression expression, string output)
{
ParameterExpression parameterExpression = (ParameterExpression)expression;
output += parameterExpression.Name;
}
private void HandleConstantExpression(Expression expression, string output)
{
ConstantExpression constantExpression = (ConstantExpression)expression;
output += constantExpression.Value.ToString();
}
代码的想法是解析表达式树并将有关节点的详细信息写入字符串变量输出。但是,当将此变量写入页面时(使用 Output()
方法),我发现它是空的。
当我使用调试器单步执行代码时,我发现当代码第一次执行 HandleParameterExpression()
时,输出被正确设置为“x”,但一旦控制从 返回>HandleParameterExpression()
回到 HandleExpression()
中的 switch 块,变量又神秘地为空。
由于字符串是引用类型,因此我应该能够在方法之间传递引用,并且应该保留方法对其值所做的更改,对吧? C# 中参数传递是否有一些我不知道的微妙之处?
I'm experimenting with parsing expression trees and have written the following code:
private void TestExpressionTree()
{
Expression<Func<int, bool>> expression = x => x == 1 || x == 2;
string output = String.Empty;
HandleExpression(expression.Body, output);
Output("Output", output);
}
private void HandleExpression(Expression expression, string output)
{
switch (expression.NodeType)
{
case ExpressionType.Conditional:
HandleConditionalExpression(expression, output);
break;
case ExpressionType.OrElse:
HandleOrElseExpression(expression, output);
break;
case ExpressionType.Equal:
HandleEqualExpression(expression, output);
break;
case ExpressionType.Parameter:
HandleParameterExpression(expression, output);
break;
case ExpressionType.Constant:
HandleConstantExpression(expression, output);
break;
}
}
private void HandleConditionalExpression(Expression expression, string output)
{
ConditionalExpression conditionalExpression = (ConditionalExpression) expression;
HandleExpression(conditionalExpression.Test, output);
}
private void HandleOrElseExpression(Expression expression, string output)
{
BinaryExpression binaryExpression = (BinaryExpression)expression;
HandleExpression(binaryExpression.Left, output);
output += "||";
HandleExpression(binaryExpression.Right, output);
}
private void HandleEqualExpression(Expression expression, string output)
{
BinaryExpression binaryExpression = (BinaryExpression)expression;
HandleExpression(binaryExpression.Left, output);
output += "=";
HandleExpression(binaryExpression.Right, output);
}
private void HandleParameterExpression(Expression expression, string output)
{
ParameterExpression parameterExpression = (ParameterExpression)expression;
output += parameterExpression.Name;
}
private void HandleConstantExpression(Expression expression, string output)
{
ConstantExpression constantExpression = (ConstantExpression)expression;
output += constantExpression.Value.ToString();
}
The idea of the code is to parse the expression tree and write details about the nodes into the string variable output. However, when this variable is written to the page (using the Output()
method), I'm finding it's empty.
When I use the debugger to step through the code, I find that output is correctly set to 'x' when the code executes HandleParameterExpression()
for the first time, but as soon as control returns from HandleParameterExpression()
back to the switch block in HandleExpression()
, the variable is mysteriously empty again.
Since strings are reference types, I should simply be able to pass the reference between the methods and changes to its value made by the methods should be retained, right? Is there some subtlety of parameter passing in C# that I'm not aware of?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
看起来您想使用
out
参数:示例:将
private void HandleExpression(Expression expression, string output)
更改为private void HandleExpression(Expression expression, out string output) )
并将HandleExpression(expression.Body, output);
替换为HandleExpression(expression.Body, out output);
然后在方法中写入
output
将会影响传递给函数的参数。Looks like you want to use
out
params:Example: Change
private void HandleExpression(Expression expression, string output)
toprivate void HandleExpression(Expression expression, out string output)
and replaceHandleExpression(expression.Body, output);
withHandleExpression(expression.Body, out output);
Then writing to
output
in the method will affect the argument passed to the function.您永远不会更改字符串内的数据,因为它是不可变的。
每次你有:
这就是说:
“output + Something”的值实际上是调用
String.Concat(output, Something)
的结果 - 即对新字符串的引用。因此,您的代码正在更改变量output
的值以引用新字符串。现有字符串中的数据保持不变。更改参数的值不会更改调用者中的相应值,除非该参数通过引用传递(使用
ref
或out
)。有关更多详细信息,请参阅我的有关参数传递的文章。请注意按值传递引用和按引用传递变量之间的区别。我建议您更改代码以使用
StringBuilder
代替。You're never changing the data within the string, because it's immutable.
Each time you have:
that's saying:
The value of "output + something" is actually the result of calling
String.Concat(output, something)
- i.e. a reference to a new string. So your code is changing the value of the variableoutput
to refer to the new string. The data in the existing string remains unchanged.Changing the value of a parameter won't change the corresponding value in the caller, unless the parameter is passed by reference (using
ref
orout
). See my article on parameter passing for more details. Note the difference between passing a reference by value, and passing a variable by reference.I suggest you change your code to use
StringBuilder
instead.您需要传入您想要通过引用实际更改的任何变量。因此,在您的示例中,您需要这样做:
然后当您调用该函数时,您需要这样做:
You need to pass in ANY variable that you want to actually change by reference. So, in your example, you would need to do it this way:
And then when you call the function, you would do it this way:
字符串是不可变的,因此通过为
output
分配另一个值,您不会更改output
,而是创建一个新的字符串变量。您可能希望将
output
参数声明为ref
。Strings are immutable, so by assigning another value to
output
, you are not changingoutput
, but creating a new string variable.You might want to declare the
output
parameter asref
.