我是否可以将C#函数限制为仅接受字符串文字?

我是否可以将C#函数限制为仅接受字符串文字?,c#,gettext,type-constraints,C#,Gettext,Type Constraints,为了允许从源代码中提取所有可翻译的消息,我们希望使用特定的“语义”Message类。只有消息才能显示到UI。通过这种方式,我们希望防止UI中出现太多未翻译的字符串 但是像Message.Create(“a”+x)这样的事件不能由gettext提取引擎提取 那么,在C语言中有没有办法确保我的函数(GetText.\uu或类似的函数)只使用字符串文本调用 还是应该以某种方式恢复预处理?有任何库/工具可以做到这一点吗?语言中没有任何东西支持必须是字符串文字的参数,没有。我个人认为这将是一种奇怪的语言“

为了允许从源代码中提取所有可翻译的消息,我们希望使用特定的“语义”
Message
类。只有消息才能显示到UI。通过这种方式,我们希望防止UI中出现太多未翻译的字符串

但是像
Message.Create(“a”+x)
这样的事件不能由gettext提取引擎提取

那么,在C语言中有没有办法确保我的函数(
GetText.\uu
或类似的函数)只使用字符串文本调用


还是应该以某种方式恢复预处理?有任何库/工具可以做到这一点吗?

语言中没有任何东西支持必须是字符串文字的参数,没有。我个人认为这将是一种奇怪的语言“功能”

我的建议是创建一个
MessageTemplate
类或类似的类,并将您的方法更改为接受
MessageTemplate
参数

然后,
MessageTemplate
类可以有一组特定的实例,其中包含您需要的所有字符串。例如:

public sealed class MessageTemplate
{
    public static MessageTemplate InvalidFilter { get; } =
        new MessageTemplate("invalid_filter");

    public static MessageTemplate Success { get; } =
        new MessageTemplate("success");

    public string Name { get; }

    private MessageTemplate(string name) => Name = name;
}
然后方法调用将如下所示:

Message.Create(MessageTemplate.Success);
优点:

  • 有效字符串都在一个地方,而不是分散在代码库中
  • 调用代码可以使用一个有用的名称(例如“Success”),即使底层字符串名称不太有用(例如“x”),这使得它更易于阅读
  • 您可以安全地传递
    MessageTemplate
    引用,因为它们是消息模板,而不仅仅是任意字符串

如果您真的只想接受字符串文字,那么最好的选择可能是为此创建一个属性,然后编写一个Roslyn分析器。这将检查每个方法调用,并验证如果参数具有该属性,则参数是字符串文本


就我个人而言,我认为这会产生不良影响,将这些神奇、脆弱的字符串常量分散到整个代码库中,但这是最接近您所要求的确切行为的。当然,这只会在与Roslyn一起构建时产生影响。

而不是确切地说什么?@将军,我将详细说明为什么您应该使用枚举,至少你奇怪的要求是,我投票决定把这个问题作为离题题来结束,因为这显然是一个xy问题,但OP没有提供足够的细节来建议一种不同的方法“提取所有可翻译的消息”,把这些消息存储在资源文件中怎么样?你把它们都放在一个地方,翻译只需要修改一行代码…我认为这是一个奇怪的语言“特性”,个人-用户练习:使用Roslyn更改C语言,使
字符串
文字在某种程度上有所不同…@Rawling:我想编写Roslyn分析器不会太难,这样您就可以向方法参数添加属性,然后检查对该方法的所有调用,如果相应的参数不是字符串文字,则引发警告。当然,对于这种情况,我更喜欢我在这里给出的答案:)这显然是一种比在代码中使用魔法字符串分散调用更好的方法,但它仍然解决了问题。最后,除了代码审查或一些预处理工具之外,没有任何东西可以保证您的助手类返回的任何消息实际上都是一个字符串文本。与其尝试强制执行这一奇怪的规则,我将寻找一种不同的解决方案。当其中一条消息必须基于某个条件写入时会发生什么情况?@InBetween:我对问题的理解并不是因为它是一个重要的字符串文字,而是因为它只是一组固定的字符串才会被接受。template类强制只使用固定的字符串集。是的,那门课需要复习以确保字符串是正确的,但仅此而已。