有没有一种编程方法来识别 C# 保留字?

发布于 2024-10-21 06:43:01 字数 234 浏览 1 评论 0原文

我正在寻找一个功能,就像

public bool IsAReservedWord(string TestWord)

我知道我可以通过从 MSDN 获取保留字列表来推出自己的功能。不过,我希望语言或 .NET 反射中内置了一些可以依赖的东西,这样当我迁移到较新版本的 C#/.NET 时就不必重新访问该函数。

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

I'm looking for a function like

public bool IsAReservedWord(string TestWord)

I know I could roll my own by grabbing a reserve word list from MSDN. However I was hoping there was something built into either the language or .NET reflection that could be relied upon so I wouldn't have to revisit the function when I move to newer versions of C#/.NET.

The reason I'm looking for this is I'm looking for a safeguard in .tt file code generation.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

等你爱我 2024-10-28 06:43:01
CSharpCodeProvider cs = new CSharpCodeProvider();
var test = cs.IsValidIdentifier("new"); // returns false
var test2 = cs.IsValidIdentifier("new1"); // returns true
CSharpCodeProvider cs = new CSharpCodeProvider();
var test = cs.IsValidIdentifier("new"); // returns false
var test2 = cs.IsValidIdentifier("new1"); // returns true
ぃ弥猫深巷。 2024-10-28 06:43:01

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(三个下划线)。

The Microsoft.CSharp.CSharpCodeGenerator has an IsKeyword(string) method that does exactly that. However, the class is internal, so you have to use reflection to access it and there's no guarantee it will be available in future versions of the .NET framework. Please note that IsKeyword doesn't take care of different versions of C#.

The public method System.CodeDom.Compiler.ICodeGenerator.IsValidIdentifier(string) rejects keywords as well. The drawback is this method does some other validations as well, so other non-keyword strings are also rejected.

Update: If you just need to produce a valid identifier rather than decide if a particular string is a keyword, you can use ICodeGenerator.CreateValidIdentifier(string). This method takes care of strings with two leading underscores as well by prefixing them with one more underscore. The same holds for keywords. Note that ICodeGenerator.CreateEscapedIdentifier(string) prefixes such strings with the @ sign.

Identifiers startings with two leading underscores are reserved for the implementation (i.e. the C# compiler and associated code generators etc.), so avoiding such identifiers from your code is generally a good idea.

Update 2: The reason to prefer ICodeGenerator.CreateValidIdentifier over ICodeGenerator.CreateEscapedIdentifier is that __x and @__x are essentially the same identifier. The following won't compile:

int __x = 10;
int @__x = 20;

In case the compiler would generate and use a __x identifier, and the user would use @__x as a result to a call to CreateEscapedIdentifier, a compilation error would occur. When using CreateValidIdentifier this situation is prevented, because the custom identifier is turned into ___x (three underscores).

太傻旳人生 2024-10-28 06:43:01

但是,我希望语言或 .NET 反射中内置了一些可以依赖的东西,这样当我迁移到较新版本的 C#/.NET 时,我就不必重新访问该函数。

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

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

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

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

However I was hoping there was something built into either the language or .NET reflection that could be relied upon so I wouldn't have to revisit the function when I move to newer versions of C#/.NET.

Note that C# has never added a new reserved keyword since v1.0. Every new keyword has been an unreserved contextual keyword.

Though it is of course possible that we might add a new reserved keyword in the future, we have tried hard to avoid doing so.

For a list of all the reserved and contextual keywords up to C# 5, see

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

鸠书 2024-10-28 06:43:01
    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);
}

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

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

Since the definition of CreateEscapedIdentifier is:

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

it will properly identify __ identifiers as reserved.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文