【问题标题】:Why is params keyword not contextual?为什么 params 关键字不是上下文相关的?
【发布时间】:2011-01-05 21:40:50
【问题描述】:

我问的原因是,它只在方法参数声明中有效,不是吗?我试图在函数体内创建一个名为“params”的变量,但这当然不是什么大问题,只是想知道 MS 选择将其设为全局关键字而不是上下文的原因。

【问题讨论】:

  • 不确定为什么部分,但如果你真的想在 c# 中将其用作变量名,请在变量名前加上 @: int @params = 1;

标签: c# .net compiler-construction


【解决方案1】:

同样可以询问任何其他关键字。例如,为什么“类”不是上下文相关的,因为它只在类声明中使用?

对我来说,关键字就是关键字。我想它极大地简化了编译的词法分析部分,不必了解上下文。

顺便说一句,您可以使用@ 符号来声明一个名为“params”(或任何其他保留关键字)的变量:

var @params = new int[] { 1, 2 };

【讨论】:

  • 谢谢,但是如果类是上下文的,那么它们将如何分离嵌套类的使用?但是有了参数,就没有其他地方可以使用它了,而且似乎很容易区分它们,但我不是像 Eric Lippert 这样的编译器大师。
  • 我认为您可以尝试通过寻找典型的类声明语法来使“类”具有上下文:[可访问性修饰符]类 [类名] {}。但我对编译器规范的了解还不够,无法知道这是否真的可行。
  • 假设“类”是上下文相关的。假设您有“class class{} class get{} class C { public class D { get”——此时您不知道 D 是否是具有“get”类型的字段(或方法)的嵌套类声明缺少名称,或者 D 是否是缺少 getter 主体的“类”类型的属性。这些情况显然是人为的,但如果我们支持该功能,那么我们必须为所有可能的此类情况提出合理的错误。这需要大量的分析、大量的规范编写和大量的测试,才能使几乎没有人受益的功能。
  • 顺便说一下,当我在 VBScript 5 中添加类时,我们确实在 VBScript 中将“类”作为新的保留字,而不是使其与上下文相关。 VBScript 的语法和语义使得很难确定“Class Foo”何时是一个类的引入,或者是对带有参数“Foo”的过程“Class”的调用。不得不添加一个新的保留字很烦人,但替代方案被确定为更糟。
  • 感谢 Eric,这正是我在“class”关键字是上下文时所想的。
【解决方案2】:

tvanoffson 的回答推测很难将“参数”与上下文相关联。其实不会那么难。考虑:

void M(params x)

在这种情况下,假设我们首先尝试查找类型“params”。如果我们能找到一个,太好了,我们完成了。如果我们不能,那么我们就有一点问题。假设例如,而不是 x 它是

void M(params Int32)

显然这是一个错误,但什么错误?我们是否应该假设 Int32 是参数名称并给出错误“您缺少类型”?我们是否应该假设 Int32 是类型并给出错误说该类型必须是数组类型,并且您缺少标识符?我们应该给出一个错误,说没有名为“params”的类型吗?在这里做什么是正确的?显然我们可以弄清楚一些事情,但并不明显。

使用上下文关键字棘手的是错误情况;让成功案例发挥作用实际上非常简单。

但实际上,很难 使上下文相关,因为使其具有上下文并不是一个真正的大胜利。使“set”和“value”上下文相关是一个巨大的胜利,因为我们假设各种各样的人都会想要使用“set”和“value”这样的名称来创建局部变量。 “params”甚至不是一个英文单词,所以似乎不太可能有人想要使用它。使其与上下文相关并没有太大的好处,因此该功能的成本是不合理的。

【讨论】:

  • 谢谢埃里克。我真的很希望能读懂你的想法。在我看来,有效案例似乎是 1。是否有可用的 params 类型? 2. 如果没有,那么必须有一个Type[]形式的类型,并且后跟一个标识符。我不是像你这样的专家,但你认为这涵盖了所有情况吗?你也是对的,它不是一个英文单词,只是认为它在某些代码中会有用,而不是写参数/(s)。
【解决方案3】:

Eric Lippert 的博客文章涵盖了 contextual and reserved keywords 及其历史。虽然它没有明确解释为什么 params 出现在保留列表中(从 1.0 开始就存在),但它暗示它属于保留字集,很难与上下文相关。 p>

【讨论】:

  • 谢谢,这就是保留字的用途?我认为这意味着它是为未来的新潜在用途保留的?
  • @Joan - 有些可能是,但大多数是保留,如“仅为此目的保留”。
【解决方案4】:

params 关键字看起来确实只在方法参数声明中有用,但我实际上同意 MS 的观点,无论如何让关键字用于实例名称并不是一个好主意。

也许他们保留了在 C# 8.0 中拥有类似功能的能力:

params Customers = DB.GetCustomerList();

或者在本地范围内也允许params

【讨论】:

  • 但那会怎样呢?对我来说,在您展示的本地范围内使用它没有多大意义,不是吗?我不确定。顺便说一句,C# 8.0 什么时候发布? :O
  • 如果我的水晶球是准确的,我想在 2017 年左右。
  • 琼 - 好问题。我不知道那会做什么。事实上,由于语法错误,我什至认为这行代码不会在 C# 8.0 中编译。
猜你喜欢
  • 2011-11-26
  • 1970-01-01
  • 2015-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-18
相关资源
最近更新 更多