What characters are allowed in C# class name?
Asked Answered
S

7

77

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.

Sutlej answered 4/6, 2009 at 13:32 Comment(9)
Is there a specific class name you are struggling with? The compiler will give pretty quick feedback as to whether or not you are ok with your name.Kinsler
Perhaps it would be better if you explained the problem you are trying to solve. It doesn't seem feasible for someone to compose a list of all possible characters that are valid for type names.Schapira
I've added some explanation. Hope it helps to find solution. Thanks!Sutlej
In your example how about using an underscore instead of the @ as this is fairly common practiceKinsler
class Person_WorkOffice_Helper_Class { }Kinsler
What is the ultimate goal you are trying to accomplish? Why do you need to divide your class name into distinguishable parts? Perhaps there is a better way.Laveen
I can not use underscores Jeremy because these parts can contain _ in them.Sutlej
Chris, I would like to have a class name as closest to source names of these parts as it can be.Sutlej
What about using namespaces instead of trying to name your classes weridly?Cryogenics
W
82

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.

Wilen answered 4/6, 2009 at 13:37 Comment(13)
I specified more what I search for. Link you provided is very complicated and I think that do not have time to search over thousands of pages to get what characters are allowed.Sutlej
As I said, it boils down to - any letter or _ for the first character - any unicode character for the rest (the character classes Lu, Ll, Lt, Lm, Lo, or Nl) - if it is a keyword, add a @ to the startWilen
I can use underscore _ inside my class name, but can't @ nor !. Are there any special characters that I can use? What is Lu, LI, Lt, Lm, Lo, NI??Sutlej
Correct. Plus that two consecutive underscore characters ("__") should not be used. They are reserved for internal use.Quarto
Character class information is at msdn.microsoft.com/en-us/library/20bw873z.aspx. Unfortunately, unicode is so big it's infeasible to give a definitive list without referring to character classes :(Wilen
Do you want to say that I can not use nothing more than letters and numbers and single underscores?Sutlej
@tomaszs No, he means that there are so many characters you can use that it wouldn't be practical to list them all here. For example you can use accented characters : àéôùÿ..., and there's a plethora of them.Assimilable
There appear to be some exceptions to this. For example, I can't declare a class named Testˆ - despite this last character (U+02C6) being in the Lm categoryUndergird
I don't think the compiler used by Visual Studio adheres to this claim. I can't, for example, compile with a class named "testᴺᵁᴸᴸ", and get Error CS1056: Unexpected Character (these characters are from Lm by the way.) Would appreciated clarity from poster on this.Merino
W.R.T my prior comment; have checked other answers and it's worth mentioning that support for characters above Unicode 3.0 is not available, which seems important to mention!Merino
@TernaryTopiary: Well.. in VS2017 v15.5.4 community, I successfuly created a local variable called thisˆthisᴺᵁᴸᴸthisHyetography
The character classes mentioned in this answer are: Lu = "Letter, Uppercase". Ll = "Letter, Lowercase". Lt = "Letter, Titlecase". Lm = "Letter, Modifier". Lo = "Letter, Other". Nl = "Number, Letter". Mn = "Mark, Nonspacing". Mc = "Mark, Spacing Combining". Nd = "Number, Decimal Digit". Pc = "Punctuation, Connector". Cf = "Other, Format".Dyestuff
Almost took it that I'm looking at chemical elements.Jonejonell
K
26

Valid identifiers in C# are defined in the C# Language Specification, item 9.4.2. The rules are very simple:

  • An identifier must start with a letter or an underscore
  • After the first character, it may contain numbers, letters, connectors, etc
  • If the identifier is a keyword, it must be prepended with “@”

source

Kinsler answered 4/6, 2009 at 13:38 Comment(4)
Could you be more specific? I've detailed in question what I look for. Hope to see more help. Thanks!Sutlej
No special charecters are allowed other than the @ or _ symbol. It has to start with a letter underscore or @ symbol and after that you are good to go.Kinsler
@JeremyCoenen Starting with @ is just for escaping keywords (@if), but then the next character must follow the same rules for the first. E.g. I cannot name a variable @1abc, because a number is not allowed as first character.Hackler
In case of dead reference: web.archive.org/web/20130315082540/http://blog.visualt4.com/…Tiatiana
H
21

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.

Hotfoot answered 29/7, 2010 at 9:32 Comment(0)
T
7

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;
    }
}
Though answered 23/3, 2020 at 19:51 Comment(0)
E
3

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:

  • Hold down ALT key
  • Type '0394' on the keypad
  • Release ALT

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.

Exemplary answered 5/6, 2009 at 2:47 Comment(1)
If you switch your keyboard entry from english to greek you can input Greek letters fast for use in mathematical expressions. This: σ=E*ε; is a valid statement.Massimo
N
0

https://github.com/2652660/A-CSV-BINS-OF.CS/blob/main/StringExtensionIdentifierTokenizationAndDevalidationTableAugmentor.CS

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];
        }
    }
}
Needlework answered 16/10, 2023 at 13:5 Comment(1)
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Demona
T
-8

Here's a an article you might find helpful: C# Coding Standards and Naming Conventions

table

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;
Tiatiana answered 10/1, 2019 at 9:3 Comment(4)
This doesn't answer the question.Geisel
I'm sorry, but why not, @ZzZombo? Have you checked out char mask column in the table? However, indeed the mask is incorrect since [A-z] != [A-Za-z].Tiatiana
Because you came up with naming conventions, not with a subset of valid characters in an identifier.Geisel
I see, thank you. In such case, I'd rather refer to the specification then indeed.Tiatiana

© 2022 - 2024 — McMap. All rights reserved.