Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/257.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么这个枚举声明现在可以工作?_C#_.net_Enums_C# 6.0 - Fatal编程技术网

C# 为什么这个枚举声明现在可以工作?

C# 为什么这个枚举声明现在可以工作?,c#,.net,enums,c#-6.0,C#,.net,Enums,C# 6.0,在回答另一个问题时,Jon Skeet提到,enums的定义有一个奇怪的地方 他指出,重新定义enum的基础类型只能使用类型别名,而不能使用框架类型(int有效,Int32无效,等等) 现在,我试图重现这一点(VS2015中的C#6/Roslyn),但我没有得出相同的结论: public enum TestEnum : UInt32 { } 及 两者都是完全有效的。为什么会这样?还是什么改变了 编辑: 所以为了澄清问题,这是C#6中的一个变化,还没有被记录下来,而且很快就会被记录下来,你可

在回答另一个问题时,Jon Skeet提到,
enums
的定义有一个奇怪的地方

他指出,重新定义
enum
的基础类型只能使用类型别名,而不能使用框架类型(
int
有效,
Int32
无效,等等)

现在,我试图重现这一点(VS2015中的C#6/Roslyn),但我没有得出相同的结论:

public enum TestEnum : UInt32
{

}

两者都是完全有效的。为什么会这样?还是什么改变了


编辑:


所以为了澄清问题,这是C#6中的一个变化,还没有被记录下来,而且很快就会被记录下来,你可以从git上的这个问题上读到,要么是新编译器的疏忽,要么是他们决定不再在语言中存在这种不一致性(?)

目前,似乎没有正式的规范,只有一个看起来不那么正式的git存储库,在那里工作正在进行:


目前看来,不为基础枚举类型使用别名应该是一个错误。该语言看起来与以前的官方规范相同。但是,由于编译器和规范似乎仍在进行中,很难说哪一种是正确的。

现在使用C#6确实很奇怪。当前进行中的规范仍然列出了以下用于在中指定基的语法:

积分类型定义为:

根据该语言规范判断,使用静态类型标识符列表中未出现的其他基类型应该被解析器拒绝,并导致语法错误

考虑到情况并非如此,有两种可能性:要么故意更改解析器以接受非别名类型,要么解析器错误地接受这些类型

如果我们看一下Roslyn的实现,那么我们就能明白为什么规范中的这一要求没有得到执行。只是不检查它,而是解析任何类型:

baseList语法baseList=null;
if(this.CurrentToken.Kind==SyntaxKind.ColonToken)
{
var colon=this.EatToken(SyntaxKind.ColonToken);
var type=this.ParseType(false);
var tmpList=_pool.AllocateSeparated();
tmpList.Add(_syntaxFactory.SimpleBaseType(type));
baseList=\u syntaxFactory.baseList(冒号,tmpList);
_免费游泳池(tmpList);
}
在这一点上,它与标准没有太大区别。因此,任何类型限制都不会应用于语法级别,而是应用于语义级别,在语义级别上,可能已经对类型别名进行了计算


所以这似乎是一个bug:要么在规范中,要么在解析器中。考虑到规范仍在进行中,这可能会在以后得到解决。

这是C#6中有意进行的语言更改,其规范仅以草稿形式发布。这是一个如此小的变化,我们总是忘记把它纳入规格


另请参见

答案发布于2008年10月18日18:52,比C#6早几年!看起来他们已经修复了这个异常。这是一个新的编译器。@ChrisF gosh,我当时在groundschool,hahaI已经提交了文件。@svick谢谢你,sir,但是基础类型不需要扩展到框架类型吗?这似乎符合定义。@DanielA.White:如果您阅读了OP链接的问题,它提到规范指定基础类型必须与
integral_类型
产品相匹配,后者仅定义为C#内置关键字的列表,其他什么都没有。这一部分在“正在进行的工作”规范中是相同的。只要看看
integral_类型
的定义,它听起来像是在任何地方使用的,它必须表示框架类型。
integral_类型
定义本身只是一个单词列表(
“sbyte”|“byte”|“short”|……
),因此,它只能引用神奇的C#特定关键字。我的理解是,在大多数地方,当谈论类型时,它指的是层次结构中更高的产品,它允许引用任意类或结构,因此
System.Int32
等。枚举位是唯一直接指
整型
产品的东西。
public enum TestEnum : UInt32
{

}
public enum MyEnum : uint
{

}
enum_base
    : ':' integral_type
    ;
integral_type
    : 'sbyte'
    | 'byte'
    | 'short'
    | 'ushort'
    | 'int'
    | 'uint'
    | 'long'
    | 'ulong'
    | 'char'
    ;
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);
}