【问题标题】:Are parameters evaluated in order when passed into a method?传递给方法时是否按顺序评估参数?
【发布时间】:2011-09-09 10:03:15
【问题描述】:

参数传入方法时是否按顺序求值?

对于 Java 总是如此,对于 C 则不是,但对于 C#,答案是什么?

样本

string.Format("byte1={0} byte2={1} byte3={2}", 
  getNextByte(), 
  getNextByte(), 
  getNextByte());

int pos=0;
byte[] arr=new byte[] {1,2,3,4,5,6};
byte getNextByte()
{
  return arr[pos++];  
}

此示例有效,但这只是运气还是规则?

【问题讨论】:

  • “Evaluated”可能是一个比“accessed”更精确的词。
  • 顺便说一句,这个问题以前有人问过。
  • @Aasmund:谢谢,我改了。

标签: c#


【解决方案1】:

是的,作为参数传递给方法的表达式总是从左到右计算。

来自 C# 4.0 语言规范:

7.5.1.2 参数列表的运行时评估

在函数成员调用(第 7.5.4 节)的运行时处理期间,按顺序评估参数列表的表达式或变量引用,从左到右,[...]

【讨论】:

  • 我不记得这是否是一种保证。你还记得或有参考吗?尽管在任何情况下都不应该依赖这个:)
  • 在语言规范中;所以是的,这是一个保证。
  • @leppie:F# 编译器依赖于这种行为。 match dict.TryGetValue(key) with true, value -> ... | false, _ -> ... 编译为 T value = default(T); Tuple<bool, T> tuple = new Tuple<bool, T>(dict.TryGetValue(key, out value), value); if (tuple.Item1) ...。
  • 你认为这也适用于params 参数,它们基本上是数组初始化的语法糖吗?
  • 根据docs.microsoft.com/en-us/dotnet/csharp/language-reference/…,应该是这样的:表达式按递增顺序初始化数组元素,从索引为零的元素开始。
【解决方案2】:

正如其他人指出的那样,语言规范要求以从左到右的顺序评估参数。

然而,全面披露,我们在 C# 4.0 中无意且无意地引入了几个错误,其中某些场景涉及命名参数、可选参数和在调用遗留 COM 对象时被省略的参数,这样在这些场景中参数的影响可能不会严格按照从左到右的顺序进行评估。处理这些功能之间交互的分析器很复杂,并且存在一些错误。

我为错误道歉;我们希望在下一个版本中修复它们。

【讨论】:

  • 谢谢,但就我而言,我只使用非常简单的参数。我没想到会有任何问题
  • @jeb:确实,几乎没有人会看到这些问题,这就是为什么我们没有发现它们,直到修复它们为时已晚。我注意到,一般来说,C# 中的所有内容都是按从左到右的顺序计算的。如果您对此主题感兴趣,请参阅 blogs.msdn.com/b/ericlippert/archive/tags/precedence 了解更多关于此主题的文章。
  • @EricLippert 你是我的英雄。
  • 博客链接断开。我想这相当于链接了什么? ericlippert.com/tag/precedence
  • @relatively_random:感谢您的留言。是的,MSFT 一直在移动我的博客存档所在的位置。最终,我会将所有内容转移到 ericlippert.com。
【解决方案3】:

来自语言规范:

在函数成员调用的运行时处理期间,参数列表的表达式或变量引用按从左到右的顺序计算。

【讨论】:

    猜你喜欢
    • 2011-10-07
    • 2013-02-21
    • 2018-11-20
    • 1970-01-01
    • 1970-01-01
    • 2011-08-30
    • 2018-11-05
    • 2011-12-17
    相关资源
    最近更新 更多