在Switch语句中使用映射的属性

时间:2017-12-07 12:52:14

标签: c#

我正在尝试创建某种映射并基于此构造switch语句。

我尝试的第一件事是:

public class Class1
{
    public void Test()
    {
        string testString_A = "A";
        string testString_B = null;
        switch (testString)
        {
            case Options.O1.aName:
                testString_B = Options.O1.bName;
                break;
            case Options.O2.aName:
                testString_B = Options.O2.bName;
                break;

        }
    }
}

public static class Options
{
    public static Option O1 = new Option()
    {
        aName = "A1",
        bName = "B1"
    };

    public static Option O2 = new Option()
    {
        aName = "A2",
        bName = "B2"
    };
}


public class Option
{
    public string aName;
    public string bName;
}

在这种情况下,编译器会抱怨切换案例需要一个常量值。

接下来,我尝试了以下内容,但它也无效。我尝试在switch语句中使用的.aName似乎无法访问。

public Class1()
{

    public void Test()
    {
        string testString = "A1";
        switch (testString)
        {
            case Options.O1.aName:
                ...

        }
    }
}


public static class Options
{
    public static Option_O1 O1 = new Option_O1();
    public static Option_O2 O2 = new Option_O2();
}


public class Option_O1
{
    public const string aName = "A1";
    public const string bName = "B1";
}

public class Option_O2
{
    public const string aName = "A2";
    public const string bName = "B2";
}

我如何实现我想要的目标?

1 个答案:

答案 0 :(得分:0)

string属性/字段变量(即使它是staticreadonly)和const字符串之间存在很大差异。 switch语句requires const语句中的文字或case值。

这解释了为什么您的第一次尝试没有成功(错误:“需要常量值”)。

在第二种情况下,虽然你显然可以这样做:

switch (testString)
{
    case Option_O1.aName:
        return Option_O1.bName;
    case Option_O2.aName:
        return Option_O2.bName;
}

但是一旦你尝试通过引入静态类容器来“欺骗”常量切换要求,你就会回到同样的问题,尽管更加神秘的编译错误:

case Options.O1.aName: // Cannot be accessed by an instance reference
    return Option_O1.bName;

替代开关

我猜这里,但似乎你需要构建一个运行时映射函数。

假设您总是希望返回相同的数据类型(字符串),我建议使用您尝试“切换”的字符串键入的Dictionary - 此映射可以在运行时构建时间。

以下是静态自举地图的示例:

public static class Options
{
    public static Option O1 = new Option()
    {
        aName = "A1",
        bName = "B1"
    };

    public static Option O2 = new Option()
    {
        aName = "A2",
        bName = "B2"
    };
}

private static IDictionary<string, Option> myOptionMap = new []
{
    Options.O1, Options.O2
}
.ToDictionary(x => x.aName);

您可以这样使用:

public string Test(string someAName)
{
    if (myOptionMap.TryGetValue(someAName, out var myOption))
    {
        return myOption.bName;
    }
    // Oops not found
    return string.Empty;
}

除非你的MVP比你的MVP更多,否则你不太可能想要为每个实例创建子选项 - Option_O1