Which other restrictions are there on names (beside the obvious uniqueness within a scope)?
Where are those defined?
Which other restrictions are there on names (beside the obvious uniqueness within a scope)?
Where are those defined?
From the PDF of ECMA-335, Partition II, section 22, "Metadata preserves name strings, as created by a compiler or code generator, unchanged. Essentially, it treats each string as an opaque blob. In particular, it preserves case. The CLI imposes no limit on the length of names stored in metadata and subsequently processed by the CLI".
If I've read this correctly and the context is correct then there's no actual limit to the length of an identifier in the CLR.
In addition to the other answers, the maximum identifier length that is accepted by the Microsoft Visual C# compiler is 511 characters. This can be tested with the following code:
class Program
{
private static void Main(string[] args)
{
int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa = 5;
}
}
The length of the variable name there is 511 characters. This code compiles, but if one character is added to the name, the compiler outputs error CS0645: Identifier too long
.
The C# language specification defines identifiers in section 2.4.2 of the Unified C# 3.0 spec. Basically it's "letter or underscore" followed by any number of "letter, decimal digit, connecting character, combining character, formatting character". To use a keyword as an identifier you need to put @ in front, e.g. int @int = 5;
I haven't looked into the CLI spec, but I know it's slightly less restrictive than the C# spec, because the C# compiler uses "unspeakable" names for things like anonymous methods - these typically include angle brackets, which are valid in the CLI but not valid in C#.
EDIT: There are no explicit name length restrictions in the C# spec, but section 2.4.2 does have one reservation:
Identifiers containing two consecutive underscore characters (U+005F) are reserved for use by the implementation. For example, an implementation might provide extended keywords that begin with two underscores.
In other words, it's implementation-specific as to whether a particular identifier beginning with __
will work. (Some compilers may have __foo
as an extended keyword, and some may not.)
According to various places in "Expert .NET 2.0 IL Assembler" (Serge Lidin, Apress), the functional CIL/CLR limit is 1,023 bytes as encoded in UTF-8. Quotes:
Page 122:
The length of either kind of name in ILAsm is not limited syntactically, but metadata rules impose certain limitations on the name length.
Page 126:
The common language runtime imposes a limitation on the full class name length, specifying that it should not exceed 1,023 bytes in UTF-8 encoding. The ILAsm compiler, however, does not enforce this limitation. Single quotes, should they be used for simple names in ILAsm, are a purely lexical tool and don’t make it to the metadata; thus, they don’t contribute to the total length of the full class name.
Page 143:
[TypeDef Table] The combined length of the strings referenced by the Name and Namespace entries must not exceed 1,023 bytes.
Page 144:
[TypeRef Table] [run time] The combined length of the strings referenced by the Name and Namespace entries must not exceed 1,023 bytes.
Page 186:
[Method Table] Name (offset in the #Strings stream). The name of the method (not including the name of the class to which the method belongs). This entry must index a string of nonzero length no longer than 1,023 bytes in UTF-8 encoding.
Looking in the Partition II Metadata docs, it states that an identifier is either an ID or an SQSTRING
An ID is described as
a contiguous string of characters which starts with either an alphabetic character or one of “_ ”, “$”, “@” or “?” and is followed by any number of alphanumeric characters or any of “_ ”, “$”, “@”, or “?”
Which would imply there's no length limit.
Visual Studio 2015 (update 3) - C# 6
Maximum class name length = 993 characters
public class AaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAAAAAZZZ
{
}
If you would add 1 more character to it, it doest not compile and surprisingly the error list is empty too!
Edit: For my colleague with VS2013 Update 3 the class name limit = 1012. Dont know the reason why.