Ответ 1
CSharpCodeProvider cs = new CSharpCodeProvider();
var test = cs.IsValidIdentifier("new"); // returns false
var test2 = cs.IsValidIdentifier("new1"); // returns true
Я ищу функцию, например
public bool IsAReservedWord(string TestWord)
Я знаю, что мог бы свернуть свой собственный, захватив резервный список слов из MSDN. Тем не менее, я надеялся, что есть что-то, встроенное в язык или .NET-отражение, на которое можно положиться, поэтому мне не пришлось бы пересматривать эту функцию при переходе на более новые версии С#/. NET.
Причина, по которой я ищу это, - это поиск защиты в генерации кода файла .tt.
CSharpCodeProvider cs = new CSharpCodeProvider();
var test = cs.IsValidIdentifier("new"); // returns false
var test2 = cs.IsValidIdentifier("new1"); // returns true
Microsoft.CSharp.CSharpCodeGenerator
имеет метод IsKeyword(string)
, который делает именно это. Тем не менее, класс является внутренним, поэтому вам нужно использовать отражение для доступа к нему, и нет гарантии, что он будет доступен в будущих версиях .NET framework. Обратите внимание, что IsKeyword
не заботится о разных версиях С#.
Открытый метод System.CodeDom.Compiler.ICodeGenerator.IsValidIdentifier(string)
также отклоняет ключевые слова. Недостатком является то, что этот метод также выполняет некоторые другие проверки, поэтому также отклоняются и другие строки без ключевого слова.
Обновление: Если вам просто нужно создать правильный идентификатор, а не решить, является ли конкретная строка ключевым словом, вы можете использовать ICodeGenerator.CreateValidIdentifier(string)
. Этот метод также заботится о строках с двумя лидирующими символами подчеркивания, префикс их еще одним подчеркиванием. То же самое относится к ключевым словам. Обратите внимание, что ICodeGenerator.CreateEscapedIdentifier(string)
префикс таких строк с знаком @
.
Идентификаторы с двумя ведущими символами подчеркивания зарезервированы для реализации (т.е. компилятор С# и связанные с ним генераторы кода и т.д.), поэтому избегать таких идентификаторов из вашего кода, как правило, хорошая идея.
Обновление 2: Причиной предпочтения ICodeGenerator.CreateValidIdentifier
over ICodeGenerator.CreateEscapedIdentifier
является то, что __x
и @__x
являются по существу тем же самым идентификатором. Следующие команды не будут компилироваться:
int __x = 10;
int @__x = 20;
В случае, если компилятор будет генерировать и использовать идентификатор __x
, и пользователь использовал бы @__x
в результате для вызова CreateEscapedIdentifier
, произошла ошибка компиляции. При использовании CreateValidIdentifier
эта ситуация предотвращается, поскольку пользовательский идентификатор превращается в ___x
(три символа подчеркивания).
Однако я надеялся, что есть что-то, встроенное в язык или .NET-отражение, на которое можно положиться, поэтому мне не придется пересматривать функцию, когда я перехожу к более новым версиям С#/. NET.
Обратите внимание, что С# никогда не добавлял новое ключевое слово зарезервированное, так как v1.0. Каждое новое ключевое слово было безоговорочным контекстуальным ключевым словом.
Хотя в будущем возможно добавить новое зарезервированное ключевое слово, мы старались не делать этого.
Список всех зарезервированных и контекстных ключевых слов до С# 5 см. в
http://ericlippert.com/2009/05/11/reserved-and-contextual-keywords/
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);
}
он будет правильно идентифицировать идентификаторы __
как зарезервированные.