Firstly, I apologise from resorting to creating a thread for this topic. I have been trying to tackle this for a while and have searched/experimented with a number of techniques but am unable to get it to work. I appreciate that I have probably been given the answer in something I have read, but I haven't been sharp enough to see it. In addition, there is a reason why I think this may not be possible, but my knowledge of c# is not sufficient for me to construct a concrete argument
Anyway TL:DR...
In a program I am creating I have a list which contains a variety of classes which all derive from the same baseclass. (This list is of type baseclass).
I wish to run though this list and either cast these baseclass reference objects into their derived classes OR create a new object and cast/copy the derived objects held in the list of baseclasses.
I think it may not be possible as C# will not know which class I need to use until runtime (edit: anything to do with c# being strongly typed?)..however, given that I can read the derived type in the list of baseclasses (using List[i].GetType), I am unsure why I cannot go ahead and make a new object.
I will try not bore you with all the incorrect experiments I have tried, but some of the first were:
foreach(baseclass bc in list)
{
Type derivedtype = bc.GetType();
//Here I can writline derivedtype .ToString() and get the name of the derived class, so seems to be holding it in there
//Then something like..
derivedtype derivedclassobject = new derivedtype () //Doesnt work
//or
bc = bc as derivedtype
//or
object o = (derivedtype )bc
//as well as things such using
Activator.CreateInstance(...);
}
Suffice to say, I'm not having any luck. I'm also sure I am showing a fundamental misunderstanding of a core concept in c# programming. I just dabble as a hobbyist unfortunately.
If anyone can tell me straight up that im trying to do some impossible, then please do. If anyone knows how to get this done, a clear explanation would be worth its weight in gold (edit: sorry, that phrase doesnt work in this case, id be very appreciative!).
Ive worked around it for now, its part of the loading/saving mechanisms for my objects in a stack used in a windows 7 phone game engine. Im just giving each object a string holding its type, and then switching this string and writing out methods explicitly for creating all the derived object types, as I rebuild the game stack from serialised saved data. I'd like to not have the user of the game engine (ie me lol) to have to remember to explicitly modify this part of the engine to handle any objects they decide to make :)
I'm wondering if a solution exists using generics, perhaps it can make better use of the type data I can pull from the objects in the list. Im going to read up on them now as they are new to me (ive come back to c# programming recently from pre c# 2.0 :) )
anyway enough excuses, thanks in advance for any help
EDIT:: Looks like it might require reflection? the activator.creatinstance() just gets me a type object, which i still need to cast! we end up further away. More and more i dont think it will work, i just dont see c# letting me do it without knowing what it will be first. again with strongly typed stuff..Is there another way to approach this sort of stuff?
Alex PatersonPosted Dec 13, 2010, 2:05 PM
My initial questions remain, but I am pretty sure I have answered them and that they are not possible in this form
1. Is it possible to declare a new object from simply a type defined in a Type object during runtime : NO, C# is type safe and wont allow it
2. Is it possible to cast an object into a type, using a type definition generated at runtime? NO, again, type safety
Why was I interested in this rather than just deserialising the full objects I needed and adding them to my stack of base objects?
To serialise all my objects requires each level of the inheritance hierachy to be Serialisable...This requires the implementation of ISerialisable interface for each class in the hierarchy. In addition, I read that you cannot serialise some things..such as Lists of objects..they need to be converted to arrays (here I think I may be incorrect, but this what I worked with to start off with)
Based on this information, and given that my objects are quite complicated, I decided it would be easier to create "properties objects" which are simple, serialisable classes that contain the variables that need to be serialised, as well as a string or type that can hold the type of object they are used to help build.
As such I currently have successfully serialised this list of "properties objects" and deserialise successfully.
The next step was to check the type of object that the "properties object" stores and which indicates the type of object the "properties object" is designed to help recreate, and then create a new instance of that object, passing it the properties object (which it is able to use to rebuild itself)
This is the point where i was unable to pull the type and create a new object (the source of my two inital questions). As such I just hardcoded a string switch which just explicitly creates the correct object based on the string type saved.
It is this manual coding I wish to remove.
SO:: From my reading, it looks like I can serialise these complex objects, but I am having trouble finding the rules about xml and/or binary serialisation (as in what type of things you can have in the class, lists, arrays, etc etc). If it turns out I am not limited by anything I want to use not being serialisable, the next step would be to just serialise the complex object, deserialise and stick it back in the stack of base objects and they should work as normal (bypassing any need to declare their type). I am hunting for a good description of the rules (I read most of the links you provided, either there is almost no restriction, or Im missing something)
However, writing methods for the Iserialise interface appears almost as time consuming as making the "properties objects", so I might stick with what I've cobbled together and know works.
Anyway, thanks for your help
Alex PatersonPosted Dec 13, 2010, 8:48 AM
Sam HobbsPosted Dec 13, 2010, 8:37 AM
Alex PatersonPosted Dec 13, 2010, 3:33 AM
The way my program works is a little different from my query above (for simplicity). For every stack object, there is a properties object which is a simple, serialisable class. When the windows phone app loses focus, all the key variables for each stack object are copied into a new object of the related properties type. These are then serialised and stored. When the phone program resumes, the list of properties objects is deserialised (works fine).
Rather than checking/switching a string in each object to work out which type of object to rebuild from properties and add to the stack, I want to use type (which I can save down in the properties object).
As this doesnt appear to work, Im going to add a rebuild method to the base class. and override this in every derived class with an explicit cast into the derived type, this is not perfect, but less hassle than the string switch
Sam HobbsPosted Dec 12, 2010, 7:47 PM
http://social.msdn.microsoft.com/Search/en-US?query=serialization%20deserialization&ac=3
There are many types of serialization and deserialization; you don't need it for communications purposes such as WCF. You probably don't want to use XML but I say that just because I assume you have chosen not to; XML might be a good choice but that is for you to decide. There are many articles and documentation about serialization; have a look at what is available in the articles iin this web site.