Какие символы разрешены в имени класса C#?

Какие символы разрешены, а какие недопустимы в имени класса C#? Не могли бы вы помочь?

РЕДАКТИРОВАТЬ: указать. Какие специальные символы разрешены? Пожалуйста, будьте конкретны, потому что ссылки на спецификации на 50 страниц на высокотехнологичном языке - не тот ответ, который мне очень поможет.

ОБЪЯСНЕНИЕ: что я пытаюсь сделать, это разделить имя класса на различимые части, например:

класс Person @ WorkOffice @ Helper @ Class

{

}

И я думаю о способе использования какого-нибудь персонажа или чего-то еще, чтобы можно было получить части Person, WorkOffice, Helper и Class из этого имени класса.

И да, я знаю, что это безумие, но мне так нужно. Я знаю, что могу использовать атрибуты и рефлексию для хранения этих данных в классе meta, но это не так, поэтому, пожалуйста, не предлагайте это решение.

7 ответов

Решение

Подробности спецификации здесь. По сути, любой символ Unicode (включая экранирование Unicode) в классах символов Lu, Ll, Lt, Lm, Lo, Nl, Mn, Mc, Nd, Pc и Cf. Первый символ является исключением, и он должен быть буквой (классы Lu, Ll, Lt, Lm или Lo) или подчеркиванием. Кроме того, если идентификатор является ключевым словом, вы должны поставить перед ним знак @. @ Необязательно в противном случае.

Допустимые идентификаторы в C# определены в Спецификации языка C#, пункт 9.4.2. Правила очень просты:

  • Идентификатор должен начинаться с буквы или подчеркивания
  • После первого символа он может содержать цифры, буквы, соединители и т. Д.
  • Если идентификатор является ключевым словом, он должен начинаться с "@"

источник

Категории Unicode можно найти здесь: http://www.dpawson.co.uk/xsl/rev2/UnicodeCategories.html

И оттуда вы можете выбрать большинство вещей из групп (из спецификаций, на которые другие тоже правильно указали):

Lu, Ll, Lt, Lm, Lo, Nl, Mn, Mc, Nd, Pc, Cf

Имейте в виду, однако, что Visual Studio (или это Resharper) не обязательно будет любить их всех, но большинство из них компилируются. Возьмем, к примеру, персонажа 30FB KATAKANA MIDDLE DOT. Он хорошо компилируется, но с IDE не очень хорошо работает. Но эта странная штука FE34. ПРЕЗЕНТАЦИОННАЯ ФОРМА ДЛЯ ВЕРТИКАЛЬНОЙ ВОЛНЫ LOW LINE работает просто отлично.

Вот разделитель, который отлично работает:

class Person〱WorkOffice〱Helper〱Class
{

}

Я не говорю, что рекомендую использовать странные символы, хотя. Но для особых случаев, как это кажется:)

РЕДАКТИРОВАТЬ: принять к сведению, что в спецификации говорится, что он допускает символы из Unicode 3.0. Я упустил это из виду и удивился, почему многие персонажи не работают, хотя они были из правильных групп. Проверьте этот вопрос для деталей.

Основываясь на символе, классифицированном в приведенных выше ответах, вы можете проверить символ, используя следующий метод расширения:

    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;
        }
    }

Обратите внимание, что, как указывает thecoop, термин "символ" в контексте Unicode намного шире, чем просто буквы алфавита.

По существу, многие символы Юникода могут быть корректно использованы в идентификаторах, даже если их сложно вводить в Windows.

В качестве примера:

  • Удерживайте клавишу ALT
  • Введите "0394" на клавиатуре
  • Выпуск ALT

Добавит греческую прописную букву Delta к вашему коду... это действительный идентификатор для C#.

Тем не менее, обратите внимание, что соответствие CLS выходит за рамки... но, судя по звукам, вы можете не слишком беспокоиться об этом в любом случае.

Вот статья, которая может оказаться вам полезной: Стандарты кодирования C# и соглашения об именах

Короче говоря, обычно первое слово / часть / буква объекта пишется строчными буквами, а класс - прописными.

Например:

HtmlHelper htmlHelper; 
FtpTransfer ftpTransfer;
UIControl uiControl;

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

Видел эту тему довольно много раз; нашел эту возню с Рослин; немного расширил - код не проверял... должно помочь вам дойти до конца и даже больше...

          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];
        }
    }
}
Другие вопросы по тегам