0

I've several classes which I'd like to select and instantiate at run time. For example:

public class MyClassA{ 
  public int property1 {get; set;}
  public string property2 {get; set;}
}

public class MyClassB{ 
  public int property1 {get; set;}
  public string property3 {get; set;}
}

Let's say, MyClassB was selected at runtime:

Type t = Type.GetType("MyNamespace.MyClassB");
Object myType = Activator.CreateInstance(t);

Now, i'd like to use myType as a type to pass to other classes/methods like this.

myType myDeserializedObject = JsonConvert.DeserializeObject<myType>(MyJsonString);

Code never compiles throwing "myType is a variable but is used like a type" error.

Is there any way or workaround to convert the activated instance to a type? Let me know if there is any other approach I should look into. Thanks!

Set
  • 47,577
  • 22
  • 132
  • 150
Felasfaw
  • 571
  • 2
  • 7
  • 20
  • You might just be better off deseralizing to a `Dictionary` or just use a `JObject.Parse(MyJsonString)` instead of trying to desearalize to a class created at runtime. – Scott Chamberlain Jun 24 '17 at 07:27
  • In cases the below answers don't work (cause no, non-generic method which accepts `Type` is available), you can still use a bit of reflection magic invoke it dynamically: https://stackoverflow.com/a/232621/455493 – Tseng Jun 24 '17 at 09:56

2 Answers2

2

You cant pass in a variable Type as a generic. Instead use

var myDeserializedObject = JsonConvert.DeserializeObject(MyJsonString, t);
Lockdowne
  • 474
  • 3
  • 7
  • I'm sure you meant: var myDeserializedObject = JsonConvert.DeserializeObject(MyJsonString, t); in my example "t" is the Type and "myType" is the instance of it. – Felasfaw Jun 24 '17 at 15:12
1

When you declare a variable as a type, or call a generic method with a type, the type checking is done at compile time. Doesn't work if the type isn't known until run time. That's two reasons why this:

myType myDeserializedObject = JsonConvert.DeserializeObject<myType>(MyJsonString);

... doesn't compile. The compiler doesn't know what type to make the myDeserializedObject, and it can't compile a version of DeserializeObject<T> that works for myType unless it knows what myType is.

There are lots of ways you could make this work but at some point you're probably going to have to do some type checking logic. Maybe something like this:

if (myType == typeof(Widget))
{
    Widget myWidget = JsonConvert.DeserializeObject<Widget>(MyJsonString);
    // do something with a Widget here
}
else if (myType == typeof(Gizmo))
{
    Gizmo myGizmo = JsonConvert.DeserializeObject<Gizmo>(MyJsonString);
    // do something with a Gizmo here
}
Robyn
  • 1,334
  • 10
  • 12