Why is my {get; private set} variable returning an empty Dictionary?

291 Views Asked by At

I am trying to use a {get; private set;} for a MorseCode translator I am building right now. The MorseToText Dictionary is supposed to be built from a TextToMorse Dictionary I have already defined. For some reason my Dictionary is empty when I use it though.

    private static Dictionary<char, string> TextToMorse = new Dictionary<char, string>()
    {
        {'A', ".-" }, {'B', "-..."}, {'C', "-.-."}, {'D', "-.."}, {'E', "."}, {'F', "..-."},
        {'G', "--."}, {'H', "...."}, {'I', ".."}, {'J', ".---"}, {'K', "-.-"}, {'L', ".-.."}, {'M', "--"},
        {'N', "-."}, {'O', "---"}, {'P', ".--."}, {'Q', "--.-"}, {'R', ".-."}, {'S', "..."}, {'T', "-"},
        {'U', "..-"}, {'V', "...-"}, {'W', ".--"}, {'X', "-..-"}, {'Y', "-.--"}, {'Z', "--.." }
    };

    private static Dictionary<string, char> _MorseToText = new Dictionary<string, char>();

    public static Dictionary<string, char> MorseToText
    {
        get { return _MorseToText; }

        private set
        {
            foreach (KeyValuePair<char, string> pair in TextToMorse)
            {
                _MorseToText.Add(pair.Value, pair.Key);
            }
        }
    }

...

        for (int i = 0; i < splitInput.Length; i++)
        {
            MorseToText.TryGetValue(splitInput[i], out char value);
            output += $"{value} ";
        }
2

There are 2 best solutions below

0
SomeBody On BEST ANSWER

You never call your setter, hence your dictionary is never filled with values. In order to call the setter, you would have to write e.g. MorseToText = new Dictionary<string,char>() or e.g. MorseToText = null at your code somewhere. Note that the value you feed into your setter will be discarded. If you called the setter twice, your code would throw an exception, because your dictionary already contains the keys. This is very confusing and because of that I recommend to use a static constructor. Maybe you also want to use a readonly Dictionary to expose your your dictionary:

private static Dictionary<char, string> TextToMorse;
private static Dictionary<string, char> _MorseToText;

public static ReadOnlyDictionary<string,char> MorseToText {get; private set; }

static YourClassName()
{
    TextToMorse = new Dictionary<char, string>()
    {
        {'A', ".-" }, {'B', "-..."}, {'C', "-.-."}, {'D', "-.."}, {'E', "."}, {'F', "..-."},
        {'G', "--."}, {'H', "...."}, {'I', ".."}, {'J', ".---"}, {'K', "-.-"}, {'L', ".-.."}, {'M', "--"},
        {'N', "-."}, {'O', "---"}, {'P', ".--."}, {'Q', "--.-"}, {'R', ".-."}, {'S', "..."}, {'T', "-"},
        {'U', "..-"}, {'V', "...-"}, {'W', ".--"}, {'X', "-..-"}, {'Y', "-.--"}, {'Z', "--.." }
    };

    _MorseToText = new Dictionary<string,char>();
    foreach (KeyValuePair<char, string> pair in TextToMorse)
    {
        _MorseToText.Add(pair.Value, pair.Key);
    }
    MorseToText = new ReadOnlyDictionary(_MorseToText);
}
0
NotFound On

One of the easiest ways to invert a Dictionary is using the ToDictionary linq function and then just swapping the Key and Value:

static Dictionary<char, string> TextToMorse = new Dictionary<char, string>()
{
    {'A', ".-" }, {'B', "-..."}, {'C', "-.-."}, {'D', "-.."}, {'E', "."}, {'F', "..-."},
    {'G', "--."}, {'H', "...."}, {'I', ".."}, {'J', ".---"}, {'K', "-.-"}, {'L', ".-.."}, {'M', "--"},
    {'N', "-."}, {'O', "---"}, {'P', ".--."}, {'Q', "--.-"}, {'R', ".-."}, {'S', "..."}, {'T', "-"},
    {'U', "..-"}, {'V', "...-"}, {'W', ".--"}, {'X', "-..-"}, {'Y', "-.--"}, {'Z', "--.." }
};
static Dictionary<string, char> MorseToText = TextToMorse.ToDictionary(x => x.Value, x => x.Key);

Currently you are using the setter wrong. The set function will be called when you assign a value to MorseToText. As example it will run when you try to set MorseToText to any instance such as MorseToText = null overriding the default behaviour you would expect with the code from your setter.