是否有一种编程方式来识别c#保留字?

时间:2011-03-10 16:26:53

标签: c# code-generation

我正在寻找像

这样的功能
public bool IsAReservedWord(string TestWord)

我知道我可以通过从MSDN获取一个保留单词列表来自己动手。但是我希望有一些内置于语言或.NET反射中的内容可以依赖,所以当我转移到新版本的C#/ .NET时,我不必重新访问该函数。

我正在寻找这个的原因是我正在寻找.tt文件代码生成的安全措施。

4 个答案:

答案 0 :(得分:24)

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

答案 1 :(得分:11)

Microsoft.CSharp.CSharpCodeGenerator有一个IsKeyword(string)方法就是这么做的。但是,该类是内部的,因此您必须使用反射来访问它,并且无法保证它将在.NET框架的未来版本中可用。请注意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(三个下划线)。

答案 2 :(得分:7)

  

但是我希望有一些内置于语言或.NET反射中的内容可以依赖,所以当我转移到更新版本的C#/ .NET时,我不必重新访问该函数。

请注意,自v1.0起,C#从未添加新的保留关键字。每个新关键字都是无保留的上下文关键字。

虽然我们可能会在将来添加新的保留关键字,但我们已尽力避免这样做。

有关C#5之前的所有保留和上下文关键字的列表,请参阅

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

答案 3 :(得分: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);
}

它会将__个标识符正确识别为保留。