2011-03-10 2 views
15

C# 예약어를 식별하는 프로그램 방식이 있습니까?

public bool IsAReservedWord(string TestWord) 

와 같은 함수를 찾고 있습니다. MSDN에서 예약어 목록을 가져 와서 내 자신을 굴릴 수 있다는 것을 알고 있습니다. 그러나 거기에 의존 할 수있는 언어 또는 .NET 리플렉션 중 하나가 내장되어 있기를 기대하고 있었기 때문에 새로운 버전의 C#/.NET으로 이동할 때 함수를 다시 방문 할 필요가 없었습니다.

내가 이것을 찾고있는 이유는 .tt 파일 코드 생성에서 보호 장치를 찾고 있기 때문입니다.

+3

의심이를 참조하십시오. 이유 중 하나는 컨텍스트 별 키워드가있을 수 있습니다. –

+0

... 문맥에 대해 신경 쓰지 않는다면 문자열이 키워드인지 여부는 꽤 간단한 테스트입니다. 그러한 테스트를 유지하려는 노력이 사소한 것 이상인 지 의심 스럽습니다. 심지어 MS는 C#의 버전을 매우 빠르게 제조 할 수 없습니다. –

답변

24
CSharpCodeProvider cs = new CSharpCodeProvider(); 
var test = cs.IsValidIdentifier("new"); // returns false 
var test2 = cs.IsValidIdentifier("new1"); // returns true 
+1

두 개의 밑줄로 시작하는 식별자를 실수로 생성하는 것을 방지 할 수는 없습니다. 그렇게하지 않도록하십시오. – Brian

+0

@Brian 나는 C# 응용 프로그램 타겟팅 .Net 4.에서이를 확인했습니다.'IsValidIdentifier' API는'var test3 = cs.IsValidIdentifier ("__ arglist")라는 밑줄로 시작하는 예약 키워드를 다음과 같이 검사 할 때 false를 반환 할 수 있습니다. ; // false를 반환합니다. 그래서 나는이 API가 그 의미에서 완전한 증거가되어야한다고 생각한다. – RBT

+0

@RBT : 두 개의 밑줄 접두사는 내부 용으로 예약되어 있으므로 절대 사용하면 안됩니다. Microsoft는 항상 두 개의 밑줄 키워드를 문서화하지 않습니다. 문맥 적 키워드는 기술적으로 유효한 식별자이므로 ('IsValidIdentifier'는 그것들을 OK로 표시한다.), 문제를 일으키기 위해 그것을 사용하고있다. 예를 들어 변수 이름으로'yield'를 사용해서는 안됩니다. 문맥 키워드를 차단하지 못하는 경우 모호한 코드를 생성하는 방법이있을 수 있습니다. – Brian

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

.

+0

이것은 작동하지 않습니다. -'CreateEscapedIdentifier'는 두 개의 밑줄이있는 문자열을 이스케이프하지 않습니다. –

+0

@Ondrej : 두 개의 밑줄이있는 문자열은 예약되어 있으므로 완벽하게 유효하다고 생각합니다. – Gabe

+0

@Gabe : 구현과의 충돌을 방지할지 여부를 결정합니다. 내 관점에서 ".t 파일 코드 생성에서 보호 장치 찾기"를 만족시키기 위해 "CreateEscapedIdentifier'는 충분히 강하지 않습니다. –

11

Microsoft.CSharp.CSharpCodeGenerator에는 정확히 IsKeyword(string) 메서드가 있습니다. 그러나 클래스는 내부 클래스이므로 액세스를 위해 리플렉션을 사용해야하며 이후 버전의 .NET 프레임 워크에서 사용할 수 있다고 보장 할 수는 없습니다. IsKeyword은 다른 버전의 C#을 처리하지 않습니다.

public 메서드 System.CodeDom.Compiler.ICodeGenerator.IsValidIdentifier(string)은 키워드도 거부합니다. 단점은이 메소드가 다른 유효성 검사도 수행하므로 다른 키워드가 아닌 문자열도 거부된다는 것입니다.

업데이트 : 특정 문자열이 키워드 인 경우 당신은 단지 유효한 식별자를 생산보다는 결정해야하는 경우, 당신은 ICodeGenerator.CreateValidIdentifier(string) 사용할 수 있습니다. 이 메서드는 앞에 두 개의 밑줄이있는 문자열을 처리합니다.에는 하나의 밑줄이 앞에 붙습니다. 키워드에 대해서도 마찬가지입니다. ICodeGenerator.CreateEscapedIdentifier(string)@ 부호가있는 문자열 앞에 붙습니다.

첫 번째 밑줄이 두 개인 시작 기호는 구현 (예 : C# 컴파일러 및 관련 코드 생성기 등) 용으로 예약되어 있으므로 코드에서 이러한 식별자를 피하는 것이 일반적으로 좋습니다.

업데이트 2 :ICodeGenerator.CreateEscapedIdentifier 이상 ICodeGenerator.CreateValidIdentifier을 선호하는 이유는 __x@__x은 본질적으로 같은 식별자 점이다. 다음은 컴파일되지 않습니다 :

int __x = 10; 
int @__x = 20; 

경우 컴파일러가 생성하는 것과 __x 식별자를 사용하고 사용자가 CreateEscapedIdentifier의 호출에 결과 @__x을 사용, 컴파일 오류가 발생합니다. CreateValidIdentifier을 사용하면 사용자 지정 식별자가 ___x (3 개의 밑줄)로 바뀌므로이 상황이 방지됩니다.

+0

정말 좋은 발견. 당신이이 문장을 이해하는 데 도움이 될 수있는 예를 들려 주시겠습니까? '이 방법은 다른 검증 방법을 사용하기 때문에 다른 비 키워드 문자열도 거부됩니다. 단점이 있습니다.'그런 키워드가 아닌 문자열 이 API가 거부 했습니까? 그것들 중 어느 하나를 아는 것은 정말로 재미있을 것입니다. – RBT

7

그러나 나는 그래서 내가 C#을 /의 최신 버전으로 이동할 때의 기능을 다시 방문하지 않았을 의존 할 수있는 언어 나 .NET 반사 중 하나에 내장 된 일이 있었다 기대했다. 그물.

v1.0부터 새로운 키워드를 추가 한 적이 없습니다. 모든 새 키워드는 예약되지 않은 문맥 키워드였습니다.

미래에 새로운 예약 키워드를 추가 할 수도 있지만, 그렇게하지 않으려 고 노력했습니다. 모든 예약 및 문맥 키워드의 목록

최대 5 C#을,

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

관련 문제