Есть ли программный способ идентифицировать зарезервированные слова c #? - PullRequest
15 голосов
/ 10 марта 2011

Я ищу такую ​​функцию, как

public bool IsAReservedWord(string TestWord)

Я знаю, что мог бы справиться самостоятельно, выбрав список резервных слов из MSDN. Тем не менее, я надеялся, что в язык или отражение .NET можно было встроить что-то, на что можно было бы положиться, поэтому мне не пришлось бы пересматривать эту функцию при переходе на более новые версии C # / .NET.

Причина, по которой я ищу это, заключается в том, что я ищу защиту в генерации кода файла .tt.

Ответы [ 4 ]

24 голосов
/ 10 марта 2011
CSharpCodeProvider cs = new CSharpCodeProvider();
var test = cs.IsValidIdentifier("new"); // returns false
var test2 = cs.IsValidIdentifier("new1"); // returns true
11 голосов
/ 10 марта 2011

Microsoft.CSharp.CSharpCodeGenerator имеет метод IsKeyword(string), который делает именно это. Однако этот класс является внутренним, поэтому для доступа к нему необходимо использовать отражение, и нет гарантии, что он будет доступен в будущих версиях .NET Framework. Обратите внимание, что IsKeyword не заботится о различных версиях C #.

Публичный метод System.CodeDom.Compiler.ICodeGenerator.IsValidIdentifier(string) также отклоняет ключевые слова. Недостатком является то, что этот метод также выполняет некоторые другие проверки, поэтому другие строки, не являющиеся ключевыми словами, также отклоняются.

Обновление: Если вам просто нужно создать действительный идентификатор, а не решать, является ли конкретная строка ключевым словом, вы можете использовать ICodeGenerator.CreateValidIdentifier(string). Этот метод также обрабатывает строки с двумя ведущими подчеркиваниями , добавляя к ним еще одно подчеркивание. То же самое относится и к ключевым словам. Обратите внимание, что ICodeGenerator.CreateEscapedIdentifier(string) ставит такие строки перед знаком @.

Идентификаторы, начинающиеся с двух ведущих символов подчеркивания, зарезервированы для реализации (т. Е. Компилятор C # и связанные генераторы кода и т. Д.), Поэтому, как правило, избегать таких идентификаторов из кода.

Обновление 2: Причина, по которой ICodeGenerator.CreateValidIdentifier предпочтительнее, чем ICodeGenerator.CreateEscapedIdentifier, заключается в том, что __x и @__x - это, по сути, один и тот же идентификатор. Следующее не скомпилируется:

int __x = 10;
int @__x = 20;

В случае, если компилятор будет генерировать и использовать идентификатор __x, а пользователь будет использовать @__x в результате вызова CreateEscapedIdentifier, произойдет ошибка компиляции. При использовании CreateValidIdentifier эта ситуация предотвращается, потому что пользовательский идентификатор превращается в ___x (три подчеркивания).

7 голосов
/ 10 марта 2011

Однако я надеялся, что в язык или отражение .NET было заложено что-то, на что можно было бы положиться, так что мне не пришлось бы пересматривать эту функцию при переходе на более новые версии C # / .NET.

Обратите внимание, что C # никогда не добавлял новое зарезервированное ключевое слово с версии 1.0. Каждое новое ключевое слово было незарезервированным контекстным ключевым словом.

Хотя, конечно, возможно, что мы добавим новое зарезервированное ключевое слово в будущем, мы изо всех сил старались избежать этого.

Список всех зарезервированных и контекстных ключевых слов до C # 5 см.

http://ericlippert.com/2009/05/11/reserved-and-contextual-keywords/

3 голосов
/ 10 марта 2011
    static System.CodeDom.Compiler.CodeDomProvider CSprovider = 
           Microsoft.CSharp.CSharpCodeProvider.CreateProvider("C#");

    public static string QuoteName(string name)
    {
        return CSprovider.CreateEscapedIdentifier(name);
    }

    public static bool IsAReservedWord(string TestWord)
    {
        return QuoteName(TestWord) != TestWord;
    }

Поскольку определение CreateEscapedIdentifier равно:

public string CreateEscapedIdentifier(string name)
{
    if (!IsKeyword(name) && !IsPrefixTwoUnderscore(name))
    {
        return name;
    }
    return ("@" + name);
}

будет правильно идентифицировать __ идентификаторы как зарезервированные.

...