问题描述
在回答另一个问题时,乔恩斯基特提到,有一个与枚举的定义
正在进行一个奇怪的事情。
他说redifining基础类型的枚举
仅与类型别名可能并没有随着框架类型( INT
是有效的,的Int32
不,等等。)
公共枚举富:UInt32的{} //无效
公共枚举酒吧:UINT {} //合法
现在我试图重现(用C#6 /罗斯林在VS2015),我并没有得出同样的结论:
$ b $ UInt32的{
}
$:乙
公开枚举TestEnum p $ p>
和
公共枚举MyEnum:UINT
{
}
都完全有效。为什么会这样?或者有什么改变。
编辑:
所以,收拾东西,它是在C#6的变化,还没有被记录在案的是,它很快就会记录,因为你可以从这个混帐问题上的
解决方案 这当然奇怪的是,这是现在用C#6.工作目前正在进行中的规范还是列出了以下的语法在的的:
enum_base
:':'integral_type
;
和整数类型定义的的:
integral_type
:为sbyte'
| 字节
| 短
| USHORT'
| '诠释'
| UINT
| 长
| ULONG
| 字符
;
通过这种语言规范来看,使用不会出现在静态类型的该列表中的某些其它基本类型。标识符应该由解析器被拒绝,并导致语法错误
由于这不是发生什么事情,有两种可能性:要么解析器故意改为接受非-aliased类型出现,或者分析器错误地接受这些。
如果我们看一下罗斯林的实施,那么我们可以看到,为什么在规范这个要求是不强制执行。该代码。因此,任何类型的限制不会对语法级别应用,但在语义层,此时类型别名可能已经评估。
所以,这似乎是一个错误:要么在本说明书中,或在分析器。鉴于该规范仍然处于进展中的工作,这可能会在以后解决。
While answering another question, Jon Skeet mentioned that there is a weird thing going on with the definition of enums
. His answer.
He states that redifining the underlying type of an enum
is only possible with the type-aliases and not with the framework types (int
is valid, Int32
not, etc.)
public enum Foo : UInt32 {} // Invalid
public enum Bar : uint {} // Valid
Now I tried to reproduce that (with C#6/Roslyn in VS2015), and I didn't come to the same conclusion:
public enum TestEnum : UInt32
{
}
and
public enum MyEnum : uint
{
}
are both totally valid. Why is that so? Or has what changed?
EDIT:
So to clear up things, it was a change in C#6, that has not been documented yet, and it will be documented soon, as you can read from this git issue on the Roslyn Github
解决方案 It’s certainly odd that this is working now with C# 6. The current in-progress specification still lists the following grammar for specifying a base in enum declarations:
enum_base
: ':' integral_type
;
And the integral types are defined as actual fixed tokens:
integral_type
: 'sbyte'
| 'byte'
| 'short'
| 'ushort'
| 'int'
| 'uint'
| 'long'
| 'ulong'
| 'char'
;
Judging by this language specification, using some other base type that does not appear in that list of static type identifiers should be rejected by the parser and cause a syntax error.
Given that that’s not what happens, there are two possibilities: Either the parser was changed deliberately to accept the non-aliased types there, or the parser incorrectly accepts those.
If we look at the implementation of Roslyn, then we can see why this requirement in the specification is not enforced. The enum declaration parser simply does not check for it but parses any type:
BaseListSyntax baseList = null;
if (this.CurrentToken.Kind == SyntaxKind.ColonToken)
{
var colon = this.EatToken(SyntaxKind.ColonToken);
var type = this.ParseType(false);
var tmpList = _pool.AllocateSeparated<BaseTypeSyntax>();
tmpList.Add(_syntaxFactory.SimpleBaseType(type));
baseList = _syntaxFactory.BaseList(colon, tmpList);
_pool.Free(tmpList);
}
At this point, it does not really differ much from the code for "normal" inheritance. So any type restriction does not apply on the syntax level, but on the semantic level—at which point type alias are probably already evaluated.
So this seems to be a bug: Either in the specification, or in the parser. Given that the specification is still a work in progress, this might be fixed later.
这篇关于这是为什么枚举声明现在的工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!