0

I am trying to create some sort of mapping and construct a switch statement based on this.

The first thing I tried was this:

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

In this scenario, compiler complains that a constant value is expected for the switch cases.

So next, I tried the following but it does not work either. The .aName I try to use in the switch statement seems not accessible.

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

How can I accomplish what I want?

John L.
  • 1,825
  • 5
  • 18
  • 45
  • It needs a constant, so use the constant: `case Option_O1.aName:` – David Dec 07 '17 at 12:56
  • @David So, there is no way I can collect them under one static class? – John L. Dec 07 '17 at 13:04
  • 1
    Well, you could make them constants on that class instead of other classes. Static or otherwise makes no difference, they're compile-time constants. I guess it's not clear what your motivation is here or what specifically you're trying to accomplish. – David Dec 07 '17 at 13:06

1 Answers1

0

There's a big difference between a string property / field variable (even if it is static or readonly), and a const string. The switch statement requires either literals, or const values in the case statements.

This explains why your first attempt didn't succeed (Error : "A Constant value is required").

In the second case, although you could obviously do this:

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

but as soon as you try and 'cheat' the constant switch requirement by introducing the static class container, you're back to the same problem, although a more cryptic compiler error:

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

Alternative to switch

I'm guessing here, but it seems that you need to build a run time mapping function.

Assuming that you always want to return the same data type (a string), I would suggest using a Dictionary keyed by the string you are trying to 'switch' on - this mapping can be built up at run time.

Here's an example of a statically bootstrapped map:

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

Which you can use like so:

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

Unless there's more to this than your MVP, it's unlikely that you'll want to subclass your options per instance - Option_O1

StuartLC
  • 104,537
  • 17
  • 209
  • 285
  • If you need to do something more complex than just return a constant string, you can also build up a map of `Func`'s, each of which could do custom processing, although each `Func` would require the same signature / shape. – StuartLC Dec 07 '17 at 13:15