名称还有哪些其他限制(除了范围内明显的唯一性)?
那些定义在哪里?
除了其他答案之外,Microsoft Visual C# 编译器接受的最大标识符长度是511 characters。这可以使用以下代码进行测试:
class Program
{
private static void Main(string[] args)
{
int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa = 5;
}
}
变量名的长度有 511 个字符。此代码可以编译,但如果在名称中添加一个字符,编译器会输出error CS0645: Identifier too long
.
来自ECMA-335 的 PDF,第 II 部分,第 22 节:
元数据保持由编译器或代码生成器创建的名称字符串不变。本质上,它将每个字符串视为一个不透明的 blob。特别是,它保留了大小写。CLI 对存储在元数据中并随后由 CLI 处理的名称的长度没有限制
如果我已正确阅读并且上下文正确,则 CLR 中标识符的长度没有实际限制。
C# 语言规范在统一 C# 3.0 规范的第 2.4.2 节中定义了标识符。基本上它是“字母或下划线”后跟任意数量的“字母、十进制数字、连接字符、组合字符、格式字符”。要将关键字用作标识符,您需要将 @ 放在前面,例如int @int = 5;
我没有研究 CLI 规范,但我知道它比 C# 规范的限制要少一些,因为 C# 编译器对匿名方法之类的东西使用“不可描述”的名称——这些通常包括尖括号,这在 CLI 中是有效的,但是在 C# 中无效。
编辑:C# 规范中没有明确的名称长度限制,但第 2.4.2 节确实有一个保留:
包含两个连续下划线字符 (U+005F) 的标识符保留供实现使用。例如,一个实现可能会提供以两个下划线开头的扩展关键字。
换句话说,以特定标识符开头的特定标识符是否有效是特定于实现的__
。(有些编译器可能有__foo
扩展关键字,有些可能没有。)
根据“Expert .NET 2.0 IL Assembler”(Serge Lidin,Apress)中的各个地方,功能 CIL/CLR 限制为 1,023 字节,以 UTF-8 编码。引号:
第 122 页:
ILAsm 中任何一种名称的长度在语法上都没有限制,但元数据规则对名称长度施加了一定的限制。
第 126 页:
公共语言运行库对完整的类名长度施加了限制,指定它在 UTF-8 编码中不应超过 1,023 个字节。但是,ILAsm 编译器不强制执行此限制。单引号,如果它们用于 ILAsm 中的简单名称,是一种纯粹的词汇工具,不会出现在元数据中;因此,它们不会影响完整类名的总长度。
第 143 页:
[TypeDef 表] Name 和 Namespace 条目引用的字符串的组合长度不得超过 1,023 字节。
第 144 页:
[TypeRef Table] [run time] Name 和 Namespace 条目引用的字符串的组合长度不得超过 1,023 字节。
第 186 页:
[方法表] 名称(#Strings 流中的偏移量)。方法的名称(不包括该方法所属的类的名称)。此条目必须索引长度不超过 1,023 字节的 UTF-8 编码的非零字符串。
Visual Studio 2015(更新 3)- C# 6
最大类名长度 = 993 个字符
public class AaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAAAAAZZZ
{
}
如果您再添加 1 个字符,它不会编译,而且令人惊讶的是错误列表也是空的!
编辑:对于我的 VS2013 Update 3 同事,类名限制 = 1012。不知道为什么。
查看 Partition II Metadata docs,它指出标识符是 ID 或 SQSTRING
一个 ID 被描述为
以字母字符或“_”、“$”、“@”或“?”之一开头的连续字符串 并且后跟任意数量的字母数字字符或“_”、“$”、“@”或“?”中的任何一个</p>
这意味着没有长度限制。