Ole*_*lik 10 c# lexer nested-generics
显然,C#和C++一样容易受到'>>'lexer困境的影响.
这个C#代码非常有效,它编译并运行得很好:
var List = new Dummy("List");
var Nullable = new Dummy("Nullable");
var Guid = new Dummy("Guid");
var x = List<Nullable<Guid>> 10;
var y = List<Nullable<Guid>> .Equals(10,20);
Run Code Online (Sandbox Code Playgroud)
您必须为上面的Dummy类重载'<'和'>>'运算符.
但编译器设法猜测在'x'情况下,意思是使用List,Nullable和Guid局部变量.在'y'的情况下,它突然决定将它们视为众所周知的类型的名称.
以下是另一个例子的更详细描述:http: //mihailik.blogspot.co.uk/2012/05/nested-generics-c-can-be-stinky.html
问题是:C#编译器如何将'a <b <c >>'解析为算术表达式或泛型类型/方法?
当然,它不会尝试在程序文本上多次"运行",直到它成功,或者它是否成功?这需要无限前瞻,而且非常复杂.
我已经被引导到C#语言规范中的7.6.4.2段:
简单名称(第7.6.2节)和成员访问(第7.6.4节)的产生可能会导致表达式语法含糊不清.
...
如果一个标记序列可以作为简单名称(第7.6.2节),成员访问(第7.6.4节)或以类型结尾的指针成员访问(第18.5.2节)进行解析(在上下文中) -argument-list(§4.4.1),检查紧跟在closing>令牌之后的令牌.如果它是其中之一
()]}:; ,.?==!= | ^
然后将type-argument-list保留为simple-name,member-access或pointer-member-access的一部分,并且丢弃令牌序列的任何其他可能的解析.否则,类型参数列表不被视为简单名称,成员访问或指针成员访问的一部分,即使没有其他可能的令牌序列解析.请注意,在解析namespace-or-type-name(§3.8)中的type-argument-list时,不应用这些规则.
因此,当涉及到type-argument-list时,确实可能出现歧义,并且通过提前查看一个令牌,他们有一种廉价的方法来解决它.
它仍然是一个未绑定的未来,因为'>>'和跟随令牌之间可能存在一个兆字节的评论,但至少规则或多或少是清楚的.最重要的是,不需要推测深度解析.
| 归档时间: |
|
| 查看次数: |
667 次 |
| 最近记录: |