在C#中编译时检查字符串格式

时间:2009-02-03 12:27:31

标签: c# .net string compiler-construction

在我的代码中,有几个字符串用作访问资源的密钥。这些密钥具有特定格式,例如

string key = "ABC123";

目前,所有这些键都存储为字符串,但我想使事情更加健壮且类型安全。理想情况下,我想在编译时检查字符串是否格式正确。

下一步是创建一个从字符串初始化的ResourceKey类。然后我可以在运行时检查字符串的格式,例如

ResourceKey key = "ABC123";

其中ResourceKey定义为:

using System.Diagnostics;
using System.Text.RegularExpressions;

class ResourceKey
{
    public string Key { get; set; }

    public static implicit operator ResourceKey (string s)
    {
        Debug.Assert(Regex.IsMatch(s, @"^[A-Z]{3}[0-9]{3}$"));
        return new ResourceKey () { Key = s };
    }
}

我真正想做的是拥有一种编译时断言,以便在有人试图使用无效密钥时程序无法构建。 e.g。

ResourceKey k1 = "ABC123"; // compiles
ResourceKey k2 = "DEF456"; // compiles
ResourceKey k3 = "hello world"; // error at compile time

有没有办法实现这个目标?

由于

5 个答案:

答案 0 :(得分:8)

您可以使用单元测试检查值。我的一个同事必须在一个项目中做类似的事情,我们需要确保某个命名空间中的所有类都应用了某些属性。

使用您的构建运行单元测试(您还是这样做吗?:)或作为集成构建的一部分。这将使您的源更清洁,并且您不必引入执行断言的代码。

答案 1 :(得分:2)

我相信我会添加一个Settings类并将它们存储在那里,而不是创建一个新类型。 Settings类可以由应用程序配置文件支持,如果需要,可以通过配置文件更改更容易地更改它们。但是,如果未在配置文件中指定它们,则会使用您设置为默认值的值。

我也会去单元测试路线。您需要在Assembly.cs文件中使用InternalsVisibleTo属性,因为如果不这样做,我认为可以在项目之外使用Settings。

答案 2 :(得分:1)

您真的希望这些密钥硬编码到您的应用中吗?将它们放在配置文件中不是更好吗?然后,如果编译后出现任何问题,那只是运行时配置问题。

答案 3 :(得分:1)

AdamRalph有一个观点,但反击点也有效,如果你在编译时正确,你将永远不会有运行时配置问题(假设正确的值不能改变)

除此之外,C#的编译时间能力是绝对的 Junk 。他们几乎没有什么可以在编译时完成。我所知道的最好的是模板where子句。如果我不得不猜测,我会说这是Anders Hejlsberg的故意设计选择,因为它似乎与其他语言相匹配

Andrew Hare关于单元测试+反思的观点与我预期的一样好。我的一个同事使用它来测试任何可以在特定情况下使用的类正确地实现了一些协议。

答案 4 :(得分:1)

如果按照与C#标识符相同的规则命名键,或者可能更具限制性,已知且有限,则可以使用枚举:

public enum ResourceKeys
{
    ABC123,
    DEF456
}
相关问题