Reputation: 26089
What characters are allowed and what is not allowed in a C# class name? Could you please help?
EDIT: To specify. What special characters are allowed? Please be specific, because links to 50 pages specs in high-technical language is not an answer that will help me a lot.
EXPLANATION: What I try to accomplish is to divide class name into distinguishable parts for example:
class Person@WorkOffice@Helper@Class
{
}
And I think about a way of using some kind of character or something else to be able to get parts Person, WorkOffice, Helper and Class from this class name.
And yes, I know it's crazy, but I need it that way. I know that I can use attributes and reflection to store this data in class meta but this is not the case, so please don't suggest this solution.
Upvotes: 78
Views: 81470
Reputation: 46108
The spec details are here (§6.4.3, p.639). Essentially, any unicode character (including unicode escapes) in the character classes Lu, Ll, Lt, Lm, Lo, Nl, Mn, Mc, Nd, Pc, and Cf. The first character is an exception and it must be a letter (classes Lu, Ll, Lt, Lm, or Lo) or an underscore. Also, if the identifier is a keyword, you must stick an @ in front of it. The @ is optional otherwise.
Upvotes: 82
Reputation: 1
Seen this thread quite a few times; found this messing around with Roslyn; expanded a bit - have not tested the code...should get you all the way there and more...
namespace StringExtensions
{
public class StringExtensions
{
private Dictionary<Range, char[]> InvalidIdentifier = new Dictionary<Range, char[]>();
public static string[] Identifiers (this string Value, int ini = 0, int fin = 128)
{
string[] identifiers = new string[]{};
foreach(string value in Value.ToString()!.Split (
InvalidIdentifiers(ini, fin),
StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries
))
{
identifiers = identifiers.Concat(Regex.Split
(
value.ToString()!,
@"(?<!^)(?=[A-Z])"
)).ToArray();
}
return identifiers;
}
public static char[] InvalidIdentifiers(int ini = 0, int fin = 128)
{
Range charRange = new Range(ini, fin);
if(InvalidIdentifier.ContainsKey(charRange) is false)
{
StringBuilder stringBuilder = new StringBuilder();
for(;ini<fin;ini++)
{
stringBuilder.Append(Convert.ToChar(ini));
}
string charMap = stringBuilder.ToString();
this.InvalidIdentifier.Add(charRange, charMap.Except(CodeIdentifier.MakeValid(charMap)).Distinct().ToArray()!);
}
return this.InvalidIdentifier[charRange];
}
}
}
Upvotes: 0
Reputation: 191
Based on the character classed in the existing answers, you can check a character using this extension method:
public static bool IsValidInIdentifier(this char c, bool firstChar = true)
{
switch (char.GetUnicodeCategory(c))
{
case UnicodeCategory.UppercaseLetter:
case UnicodeCategory.LowercaseLetter:
case UnicodeCategory.TitlecaseLetter:
case UnicodeCategory.ModifierLetter:
case UnicodeCategory.OtherLetter:
// Always allowed in C# identifiers
return true;
case UnicodeCategory.LetterNumber:
case UnicodeCategory.NonSpacingMark:
case UnicodeCategory.SpacingCombiningMark:
case UnicodeCategory.DecimalDigitNumber:
case UnicodeCategory.ConnectorPunctuation:
case UnicodeCategory.Format:
// Only allowed after first char
return !firstChar;
default:
return false;
}
}
Upvotes: 7
Reputation: 17724
The Unicode categories can be found here: http://www.dpawson.co.uk/xsl/rev2/UnicodeCategories.html
From there, you can pick most things from within the groups (from the specs, that others have correctly pointed to too):
Lu, Ll, Lt, Lm, Lo, Nl, Mn, Mc, Nd, Pc, Cf
Be aware though, that Visual Studio (or is it ReSharper) won't necessarily be fond of them all, but most of them do compile. Take, for example, the character 30FB KATAKANA MIDDLE DOT. It compiles fine, but it doesn't play nice with the IDE. But this strange thingy FE34 PRESENTATION FORM FOR VERTICAL WAVY LOW LINE works just fine.
Here's a seperator that works fine:
class Person〱WorkOffice〱Helper〱Class
{
}
I'm not saying I recommend using strange characters though. But for special occasions as this seems to be :)
Take note that the specification says that it allows characters from Unicode 3.0. I overlooked that and wondered why a lot of characters wouldn't work, though they were from the right groups. Check this question for details.
Upvotes: 21
Reputation: 1564
Here's a an article you might find helpful: C# Coding Standards and Naming Conventions
In short, in common, first word/part/letter of object is lowercase while class's is uppercase.
For example:
HtmlHelper htmlHelper;
FtpTransfer ftpTransfer;
UIControl uiControl;
Upvotes: -8
Reputation: 1075
Valid identifiers in C# are defined in the C# Language Specification, item 9.4.2. The rules are very simple:
Upvotes: 26
Reputation: 20131
Note that as thecoop indicates, the term 'character' in the context of Unicode is a lot broader than just alphabetical letters.
Basically a lot of Unicode symbols can be validly used in identifiers, even if they can be a bit tough to type in Windows.
As an example:
Will add a greek uppercase Delta to your code... this is a valid identifier letter as far as C# is concerned.
Note however that CLS compliance goes out the window... but by the sounds of it you may not be too concerned about that anyway.
Upvotes: 3