Reflection - from Type to Class (not instance of class)
-
hello guys, How do I write something like this?
string json = null; Type\[\] types = Assembly.GetExecutingAssembly().GetTypes(); var carTypes = (from type in types where type.IsClass && type == typeof(Car) select type); foreach(var carType in carTypes ) { string typeName = carType .Name; string jsonFile = typeName + ".json"; json = File.ReadAllText(jsonFile); // How can I not hardcode "Porche" here and instead use "carType"? IList cars = Newtonsoft.Json.JsonConvert.DeserializeObject\>(json); }
Here, Porche is a sub class of Car - Both "Porche" and "Car" are Class. In additional to Porche, we have Toyata, BMW, Tesla... I want to dynamically retrieve them via Reflection (avoid hardcoding) "cars" is a list of instances of cars. "carType" is Type. How can I use "carType" in JsonConvert.DerserializeObject which take List<$CLASS$> as argument? IList<someReflectionAPI(carType)> cars = Newtonsoft.Json.JsonConvert.DeserializeObjectsomeReflectionAPI(carType)>>(json); Thanks
dev
-
hello guys, How do I write something like this?
string json = null; Type\[\] types = Assembly.GetExecutingAssembly().GetTypes(); var carTypes = (from type in types where type.IsClass && type == typeof(Car) select type); foreach(var carType in carTypes ) { string typeName = carType .Name; string jsonFile = typeName + ".json"; json = File.ReadAllText(jsonFile); // How can I not hardcode "Porche" here and instead use "carType"? IList cars = Newtonsoft.Json.JsonConvert.DeserializeObject\>(json); }
Here, Porche is a sub class of Car - Both "Porche" and "Car" are Class. In additional to Porche, we have Toyata, BMW, Tesla... I want to dynamically retrieve them via Reflection (avoid hardcoding) "cars" is a list of instances of cars. "carType" is Type. How can I use "carType" in JsonConvert.DerserializeObject which take List<$CLASS$> as argument? IList<someReflectionAPI(carType)> cars = Newtonsoft.Json.JsonConvert.DeserializeObjectsomeReflectionAPI(carType)>>(json); Thanks
dev
Why? Why not just return a List<Car> - the base type for the derived classes? All you have to do is tell Newtonsoft what you are doing:
public abstract class Car { public int InCar { get; set; } } public class Porche : Car { public string InPorche { get; set; } } public class Toyota: Car { public int InToyota { get; set; } } Porche p = new Porche(); p.InCar = 111; p.InPorche = "ppp"; Toyota t = new Toyota(); t.InCar = 222; t.InToyota = 666; List cars = new List() { p, t }; JsonSerializerSettings settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All }; string json = JsonConvert.SerializeObject(cars, settings); List result =JsonConvert.DeserializeObject\>(json, settings);
And it will sort it all out.
Sent from my Amstrad PC 1640 Never throw anything away, Griff Bad command or file name. Bad, bad command! Sit! Stay! Staaaay... AntiTwitter: @DalekDave is now a follower!
-
hello guys, How do I write something like this?
string json = null; Type\[\] types = Assembly.GetExecutingAssembly().GetTypes(); var carTypes = (from type in types where type.IsClass && type == typeof(Car) select type); foreach(var carType in carTypes ) { string typeName = carType .Name; string jsonFile = typeName + ".json"; json = File.ReadAllText(jsonFile); // How can I not hardcode "Porche" here and instead use "carType"? IList cars = Newtonsoft.Json.JsonConvert.DeserializeObject\>(json); }
Here, Porche is a sub class of Car - Both "Porche" and "Car" are Class. In additional to Porche, we have Toyata, BMW, Tesla... I want to dynamically retrieve them via Reflection (avoid hardcoding) "cars" is a list of instances of cars. "carType" is Type. How can I use "carType" in JsonConvert.DerserializeObject which take List<$CLASS$> as argument? IList<someReflectionAPI(carType)> cars = Newtonsoft.Json.JsonConvert.DeserializeObjectsomeReflectionAPI(carType)>>(json); Thanks
dev
As said, it's generally best to work with the base class if possible, but to answer your specific question you can use reflection to create and call generic methods. c# - How do I use reflection to call a generic method? - Stack Overflow[^] Other examples out there if you google.
-
hello guys, How do I write something like this?
string json = null; Type\[\] types = Assembly.GetExecutingAssembly().GetTypes(); var carTypes = (from type in types where type.IsClass && type == typeof(Car) select type); foreach(var carType in carTypes ) { string typeName = carType .Name; string jsonFile = typeName + ".json"; json = File.ReadAllText(jsonFile); // How can I not hardcode "Porche" here and instead use "carType"? IList cars = Newtonsoft.Json.JsonConvert.DeserializeObject\>(json); }
Here, Porche is a sub class of Car - Both "Porche" and "Car" are Class. In additional to Porche, we have Toyata, BMW, Tesla... I want to dynamically retrieve them via Reflection (avoid hardcoding) "cars" is a list of instances of cars. "carType" is Type. How can I use "carType" in JsonConvert.DerserializeObject which take List<$CLASS$> as argument? IList<someReflectionAPI(carType)> cars = Newtonsoft.Json.JsonConvert.DeserializeObjectsomeReflectionAPI(carType)>>(json); Thanks
dev
devvvy wrote:
var carTypes = (from type in types
where type.IsClass && type == typeof(Car)
select type);That's not going to do what you want. You're trying to find all sub-classes of the
Car
type, but your query is looking for types which are exactly theCar
type. I suspect you want to use Type.IsAssignableFrom(Type)[^] :var carTypes = (from type in types
where type.IsClass && !type.IsAbstract && type.IsAssignableFrom(typeof(Car))
select type);JsonConvert
provides a non-generic method[^] you can use to deserialize your data. To access the result, you need to use a covariant interface[^] combined with the base type. For example:var listType = typeof(List<>).MakeGenericType(carType);
var cars = (IReadOnlyList<Car>)Newtonsoft.Json.JsonConvert.DeserializeObject(json, listType);
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer