C# 将字符串参数约束为特定类中的常量

C# 将字符串参数约束为特定类中的常量,c#,string,parameters,parameter-passing,constants,C#,String,Parameters,Parameter Passing,Constants,这可能是一个非常愚蠢的问题,但是:我有一个函数,它接受一个字符串,我想确保这个字符串是一个特定类中的常量。本质上,我要寻找的效果是枚举的作用: enum MyEnum {...} void doStuff(MyEnum constValue) {...} 除字符串外: static class MyFakeStringEnum { public const string Value1 = "value1"; public const string Value2 = "value

这可能是一个非常愚蠢的问题,但是:我有一个函数,它接受一个字符串,我想确保这个字符串是一个特定类中的常量。本质上,我要寻找的效果是枚举的作用:

enum MyEnum {...}
void doStuff(MyEnum constValue) {...}
除字符串外:

static class MyFakeStringEnum {
    public const string Value1 = "value1";
    public const string Value2 = "value2";
}
// Ideally:
void doStuff(MyFakeStringEnum constValue) {...}
// Reality:
void doStuff(string constValue) {...}
我知道这在技术上可以通过做一些事情来实现

public static class MyFakeStringEnum {
    public struct StringEnumValue {
        public string Value { get; private set; }
        public StringEnumValue(string v) { Value = v; }
    }
    public static readonly StringEnumValue Value1 = new StringEnumValue("value1");
    public static readonly StringEnumValue Value2 = new StringEnumValue("value2");
}
void doStuff(MyFakeStringEnum.StringEnumValue constValue) {...}
但让一个对象只存储一个值感觉有点过分了

如果没有额外的代码层和开销,这是可行的吗

编辑:虽然枚举确实可以用于字符串,但出于以下几个原因,我希望避免使用它:

  • 字符串值不一定是枚举的1:1转换。如果我有一个空格,不同的大小写,不同的字符集/语言,等等。我必须在我想使用枚举的每个函数中转换枚举。这可能不会带来很大的开销,也不会对性能造成任何影响,但仍然应该避免——特别是当这意味着我总是在改变一些应该是常量的东西时

  • 即使我使用一个单独的字符串数组映射来解决上述函数,我仍然必须访问翻译,而不是直接使用枚举。一张地图也意味着同一数据有两个来源

  • 我对不同数据类型的这个概念感兴趣,例如浮点数、ulongs等,它们不能很容易地用枚举名称表示或存储为枚举值


至于string->enum,首先使用enum的意义在于我可以依靠intellisense给我一个存在的常量;我不想等到编译时或运行时才知道。传入实际字符串将是duck类型,这是我在强类型语言中绝对不想做的事情。

我建议您创建一个枚举,并将字符串值解析为枚举成员。 您可以使用该方法来实现这一点。如果提供的值不是有效成员,则抛出ArgumentException

using System;

class Program
{
    enum MyEnum
    {
        FirstValue,
        SecondValue,
        ThirdValue,
        FourthValue
    }

    public static void doStuff(string constValue)
    {
        var parsedValue = Enum.Parse(typeof(MyEnum), constValue);

        Console.WriteLine($"Type: { parsedValue.GetType() }, value: { parsedValue }");
    }

    static void Main(string[] args)
    {
        doStuff("FirstValue");      // Runs 
        doStuff("FirstValuesss");   // Throws ArgumentException
    }
}

创建一个具有可理解名称的类并显式地告诉方法的使用者应该使用哪些值不是开销。您已经可以将枚举值的名称用作字符串。你还需要什么?无论如何,枚举并不真正约束方法只接受定义的值;您始终可以将枚举的支持类型强制转换的实例传递到枚举类型,即使该值未在枚举中定义。如果您需要一种方法将枚举“映射”到字符串表示形式(就像您在Internationalisation中必须做的那样),简单的字符串数组也可以。核心枚举只是分组的整数常量,从0开始。为什么不使用枚举呢?使用字符串有什么好处?类似于TypeScript的“字符串文字类型”在C#中会很好。为什么不使用Enum.TryParse?我想我已经读到,使用异常测试有效性确实会产生开销。例外情况是针对意外情况而非预期情况。您有权。特里帕斯比原来的问题好。无论如何,这并不重要,因为问题已经改变了。