代码之家  ›  专栏  ›  技术社区  ›  roomaroo

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

  •  6
  • roomaroo  · 技术社区  · 17 年前

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

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

    我真正想做的是有一种编译时断言,这样如果有人试图使用无效密钥,程序就无法构建。例如

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

    有没有办法做到这一点?

    谢谢

    5 回复  |  直到 17 年前
        1
  •  8
  •   Andrew Hare    17 年前

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

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

        2
  •  2
  •   tvanfosson    17 年前

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

    我也会走单元测试路线。您需要在程序集中使用InternalsVisibleTo属性。cs文件,因为我不认为设置可以在项目之外使用,如果你不这样做。

        3
  •  1
  •   Adam Ralph    17 年前

    你真的想把这些密钥硬编码到你的应用程序中吗?把它们放在配置文件中不是更好吗?如果编译后出现任何问题,那就是运行时配置问题。

        4
  •  1
  •   BCS    17 年前

    AdamRalph有一个点,但计数器点也可以工作,如果在编译时正确,则永远不会出现运行时配置问题(假设正确的值不能更改)

    除此之外,C#的编译时能力是绝对的 废旧物品 .在编译时,它们几乎无法完成任何操作。我所知道的最有用的是模板 where 条款如果非要我猜的话,我会说这是安德斯·海尔斯伯格有意做出的设计选择,因为它似乎与语言的其他部分相匹配

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

        5
  •  1
  •   Lasse V. Karlsen    17 年前

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

    public enum ResourceKeys
    {
        ABC123,
        DEF456
    }