0

I have some code that I feel like I should be able to shorten incredibly, but I can't figure out how to do it.

I have a base class called Message and may classes that derive from it.

namespace ModalVR {
    public class Message {
        public string message;

        public Message() {
            this.message = this.ToString();
        }
    }
}

The subclasses get converted to JSON, and I have a function that receives this JSON and I need to create the appropriate class. However the function that does it has a huge case statement and I feel that there must be a better way of doing this. This is what that function looks like.

public Message ConstructMessageFromJSON(string JSON) {
    string messageName = JsonUtility.FromJson<Message>(JSON).message;

    Message derivedMessage = null;

    switch(messageName) {
        case "ModalVR.GetBatteryInfo": {
            derivedMessage = JsonUtility.FromJson<GetBatteryInfo>(JSON);
            break;
        }

        case "ModalVR.GetBatteryInfoResponse": {
            derivedMessage = JsonUtility.FromJson<GetBatteryInfoResponse>(JSON);
            break;
        }

        // Many more case statements snipped out

        default: {
            LogManager.Log("Received unknown message of " + messageName, LogManager.LogLevel.Error);
            break;
        }
    }

    return derivedMessage;
}

Is there any way I can replace this huge case statement with something simpler?

Thanks in advance John Lawrie

Dalanchoo
  • 177
  • 1
  • 3
  • 17

2 Answers2

1

Using reflection only, you can do:

string messageName = "ModalVR.GetBatteryInfo";
Type messageType = Assembly.GetAssembly(typeof(Message)).GetType(messageName);
Message derivedMessage = (Message)JsonUtility.FromJson(json, messageType);

It retrieves the Assembly in which you have defined your Message class and then search for the requested type in this assembly.

Arnaud Develay
  • 3,920
  • 2
  • 15
  • 27
  • This is exactly what I needed. It is the best solution since it deals with the addition of more messages without requiring any additional code. Thanks – Dalanchoo May 25 '17 at 19:11
0

The easiest way would be to create a dictionary like that:

    var typeMatches = new Dictionary<string, Type>
    {
        {"ModalVR.GetBatteryInfo", typeof(GetBatteryInfo)}
    };

and then just get the value from it: (that's C# 7)

    if (!typeMatches.TryGetValue(messageName, out var messageType))
    {
        LogManager.Log("Received unknown message of " + messageName, LogManager.LogLevel.Error);
        return;
    }

    var derivedMessage = (Message) JsonUtility.FromJson(JSON, messageType);
Snicker
  • 957
  • 10
  • 16