【问题标题】:Using A Mapping's Properties In A Switch Statement在 Switch 语句中使用映射的属性
【发布时间】:2017-12-07 12:52:13
【问题描述】:

我正在尝试创建某种映射并基于此构造一个 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 case 需要一个常量值。

接下来,我尝试了以下方法,但它也不起作用。我尝试在 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";
}

我怎样才能完成我想要的?

【问题讨论】:

  • 需要常量,所以使用常量:case Option_O1.aName:
  • @David 那么,我无法在一个静态类下收集它们吗?
  • 好吧,你可以让它们在那个类而不是其他类上成为常量。静态或其他没有区别,它们是编译时常量。我想目前还不清楚你的动机是什么,或者你具体想要完成什么。

标签: c#


【解决方案1】:

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

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

在第二种情况下,尽管您显然可以这样做:

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 之外还有更多内容,否则您不太可能希望为每个实例的选项子类化 - Option_O1

【讨论】:

  • 如果你需要做一些比仅仅返回一个常量字符串更复杂的事情,你也可以建立一个Func的映射,每个都可以做自定义处理,虽然每个Func需要相同的签名/形状。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-01-17
  • 2020-02-03
  • 1970-01-01
  • 1970-01-01
  • 2022-06-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多