C#语法中的"base"

7

我正在研究C# 5.0的语法,但不太理解“base”的用法。在参考手册中,定义了“基类访问”的概念:

base-access:
    base   .   identifier
    base   [   expression-list   ]

“base”是一个关键字,而且似乎只有这种情况。但是,我遇到了一些C#输入,例如

base.WithAdditionalDiagnostics<TNode>(node, diagnostics);

有人能指出这个语法规则是指什么吗?由于“base”看起来是一个普通的关键字,而不是上下文相关的,我认为这种情况应该有一个特定的语法规则,并且base不能简单地成为标识符。

我无法指向具体的语法规则,但我可以告诉你 base 用于引用从另一个类派生的类。通常在重写方法或构造函数时使用它来访问超类的状态或行为。 - Brian Driscoll
1
如果您能提供C# 5.0参考手册的链接,可能会有所帮助。 - Justin
1
我不确定我理解你的问题。我不确定如何解释“似乎这是唯一的情况”,也不确定“这个语法规则指的是哪一个”(因为任何特定语句的解释都涉及多个语法规则)。 - Damien_The_Unbeliever
1
@Damien_The_Unbeliever 由于base.后必须跟标识符,而WithAdditionalDiagnostics<TNode>不是标识符,并且似乎没有任何规则允许基类访问后面跟着类型参数列表,所以这个表达式在语法上如何有效?这就是我在阅读这个问题后思考的问题,也是我认为Ali在询问的问题。 - user743382
1
@PieterWitvoet 我电脑上安装的Visual Studio 2013附带了C# 5规范,其中包含与问题中相同的产生物。 - user743382
显示剩余2条评论
1个回答

11

我相信它实际上应该是这样的

base-access:
    base   .   identifier type-argument-list_opt
    base   [   expression-list   ]

...这将使其与成员访问完全相同:

member-access:
    primary-expression   .   identifier   type-argument-list_opt
    predefined-type   .   identifier   type-argument-list_opt
    qualified-alias-member   .   identifier   type-argument-list_opt

换句话说,在表达式中
base.WithAdditionalDiagnostics<TNode>(node, diagnostics);

只有

base.WithAdditionalDiagnostics<TNode>

base-access 部分是基础访问部分 - 其余部分被解析为其他调用,例如 x.WithAdditionalDiagnostics<TNode>(node, diagnostics)

来自 C# 5 规范的第 7.6.8 节:

在绑定时,形如 base.Ibase[E] 的基础访问表达式会被评估,就像它们写成了 ((B)this).I((B)this)[E] 一样,其中 B 是发生构造的类或结构体的基类。因此,base.Ibase[E] 对应于 this.Ithis[E],只不过 this 被视为基类的实例。

但是,如果没有额外的 type-argument-listopt,我认为您现有的表达式将无法解析。

这在ECMA-334规范的第4版中已经正确说明;我会将其作为一个错误与C#规范一起修正(并确保它不会在第5版中出现问题)。


2
@JeroenVannevel:不,那是我拥有的相同规格 - 我是说第一个选项中存在一个错误。 - Jon Skeet
1
明白了,我以为你在纠正楼主。那样就说得通了。 - Jeroen Vannevel
1
@Ali:是的,人们绝对会写A.X<Blah>。它的意思是“在A(或A的类型)中调用方法X并使用类型参数Blah。”就个人而言,我认为它看起来比Java中紧跟在点号后面要好得多。这只是一种不同的参数 :) 我不能说太多关于语法的微妙之处,但也许需要类型参数列表才能执行成员查找,因为在C#中,成员可以通过泛型性进行重载。(至少,在C#和Java之间的另一个差异可能与此相关...) - Jon Skeet
@JonSkeet 谢谢!我的意思是A.X<Blah>能否独立存在而不需要调用,也就是说不需要成为A.X<Blah>(arg1, arg2)的一部分。在C#中是否有泛型成员访问方式不需要调用? - Wickoo
1
@Ali:可以,作为方法组转换:例如,如果Foo的签名为T Foo<T>(),则Func<string> x = Foo<string>;是有效的。 - Jon Skeet
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接