How to use string resource in switch statement

Viewed 236

Is there a way to use a string resource with a switch statement? After trying to obtain a string resource programmatically, an error is returned.

Error

'resourceLoader' is variable but is used like a type

C#

public class PageConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        var resourceLoader = Windows.ApplicationModel.Resources.ResourceLoader.GetForCurrentView();

        Type page = null;
        switch (value as string)
        {
            case resourceLoader.GetString("SteveJohnson/Text"):
                page = typeof(FirstPage);
                break;
            case resourceLoader.GetString("PeteDavidson/Text"):
                page = typeof(SecondPage);
                break;
            case resourceLoader.GetString("OneDrive/Text"):
                page = typeof(FistPage);
                break;
            case resourceLoader.GetString("Twitter/Text"):
                page = typeof(SecondPage);
                break;
            default:
                break;
        }

        return page;
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        throw new NotImplementedException();
    }
}
2 Answers

Are you looking for pattern matching? It's only something I've found recently (it's a C# 7 feature which I came across in this link) and what you're doing is a little different from the use case I had but I've just run a quick test with pseudo code (calling a method of another class which takes and returns a string from the switch statement) which seemed to work. For what you're doing I think you'd have something like this:

switch (value)
{
    case string _ when (resourceLoader.GetString("SteveJohnson/Text") == value as string):
                    page = typeof(FistPage);
                    break;
    case string _ when (resourceLoader.GetString("PeteDavidson/Text") == value as string):
                    page = typeof(SecondPage);
                    break;

I think you need to take a step back and look at why you want a switch statement: probably to have a readable block of code. You could easily do the same with a couple of if()s:

var resourceLoader = Windows.ApplicationModel.Resources.ResourceLoader.GetForCurrentView();

Type page = null;
if (value == resourceLoader.GetString("SteveJohnson/Text"))
    page = typeof(FirstPage);
else if (value == resourceLoader.GetString("PeteDavidson/Text"))
    page = typeof(SecondPage);
else if (value == resourceLoader.GetString("OneDrive/Text"))
    page = typeof(FistPage);
else if (value == resourceLoader.GetString("Twitter/Text"))
    page = typeof(SecondPage);      

return page;

Now you could rewrite this using pattern when clauses to shoehorn it into a switch, but I don't think that's the appropriate construct here, as it doesn't really increase readability. You could opt for a Dictionary with options instead:

var pageTypes = new Dictionary<string, Type>
{
    { resourceLoader.GetString("SteveJohnson/Text"), typeof(FirstPage) },
    { resourceLoader.GetString("PeteDavidson/Text"), typeof(SecondPage) },
    { resourceLoader.GetString("OneDrive/Text"), typeof(FirstPage) },
    { resourceLoader.GetString("Twitter/Text"), typeof(SecondPage) },
};

// Defaults to `null` when not mached
pageTypes.TryGetValue((string)value, out Type page);
return page;

You could even cache the resource lookups by initializing this dictionary once, for example in the constructor of the containing class.

Related