DannyT Posted August 25, 2005 Posted August 25, 2005 (edited) I want to instantiate a new variable to the same type as another in c# E.g. public ArrayList createList(DataTable dt, DataEntity mytype) foreach (DataRow row in dt.Rows) { myEntity = new mytype.GetType(); // THIS DOESN'T WORK myEntity.Create(row); myCollection.Add(myEntity); } } I'm trying to intantiate myEntity based on the base class of mytype (which inherits DataEntity). Any suggestions mucho appreciated :S Edited August 26, 2005 by DannyT Quote
mskeel Posted August 25, 2005 Posted August 25, 2005 What you are trying to do is not possible. The type Becuase DataEntity is the base class, you can't cast mytype to just anything that inherits DataEntity. Look at it from the compiler's perspective. If I hand you a DataEntity and I tell you it's a DataEntity can you tell me whether it's a RegularDataEntity, a SuperDataEntity, or a just plain DataEntity? You can cast an inherited class up (to the base class) but you can't cast the base class down to an inherited class. That is the trouble you are running into. What about overloading your createList() method to handle more than just the inherited class? Quote
IngisKahn Posted August 25, 2005 Posted August 25, 2005 DataEntity myEntity = (DataEntity)myType.GetType().GetConstructor(Type.EmptyTypes).Invoke(null) C'mon mskeel, this .NET after all! :) Quote "Who is John Galt?"
mskeel Posted August 25, 2005 Posted August 25, 2005 It is true. I do experience old school C-itous frenquently! And Duh....what was I thinking? Of course that makes sense. That's why you can cram things into an ArrayList without everything barfing -- everything inherits from Object so if you know what the thing in the list is supposed to be you can use it as normal event though it comes out of the list as an Object. Right? But, the thing I don't quite get, though, and I think why I said this can't be done: So you created a new DataEntity using the constructor for possibly a sub-class of DataEntity. All you know is that it has DataEntity as the base class. How are you ever going to know what it really is? In other words, who cares that you just created a SuperDataEntity class -- it's always going to look like a DataEntity class and becuase you still don't really know what it is (becuase it could be anything), you can never actually use the SuperDataEntity specific methods becuase it is very likely that the created object isn't a SuperDataEntity. What have you actually accomplished by creating the (possibly)sub-class of the base class and then casting it to the base class? My guess is that there are a few more tricks that will allow you to make all of this work on the fly? And I should have known better than to say it can't be done. If it is possilbe to execute private methods from outside the class with a simple .Net trick, then there really isn't much that you can't do. Quote
IngisKahn Posted August 25, 2005 Posted August 25, 2005 You'd want to do this because maybe something special needs to be done in the constructor or in overridden functions or you'll be testing the type later on. It works because GetType doesn't return the type of the variable, it returns the type of the instance. An object needs to know it's actual type otherwise virtual functions could not work. Quote "Who is John Galt?"
mskeel Posted August 25, 2005 Posted August 25, 2005 Right. I understand that part. Now, how does the user know? Quote
mskeel Posted August 25, 2005 Posted August 25, 2005 And furthermore, why would you ever want to do this? This seems like extremely bad practice to me -- have you backed yourself into an inheritance heirarchy corner? Perhaps that is why the functionality is so awkward and not available in other languages? There must be a better way to handle whatever it is that it trying to be accomplished here. Just becuase you can it doesn't always mean that you shoud. This feels like a hack and could be exposing design flaws. Quote
Administrators PlausiblyDamp Posted August 25, 2005 Administrators Posted August 25, 2005 It may help if you explain why you need to do things this way? If you really need to instantiate a variable and dynamically select it's type then you may want to consider implementin a factory pattern and encapsulate the logic behind the variable creation. Quote Posting Guidelines FAQ Post Formatting Intellectuals solve problems; geniuses prevent them. -- Albert Einstein
DannyT Posted August 25, 2005 Author Posted August 25, 2005 (edited) It may help if you explain why you need to do things this way? If you really need to instantiate a variable and dynamically select it's type then you may want to consider implementin a factory pattern and encapsulate the logic behind the variable creation. This is actually a method of a factory class implemented because i wanted to perform a common function with the type created by the factory which i was previously doing in the factory. E.g. //(before) public class MemberCollectionFactory { public ArrayList CreateCollection(DataEntity member, string type) { myCollection.Clear(); switch (type) { case "myString1": foreach (DataRow row in dt.Rows) { myEntity = new MyType1; myEntity.Create(row); // MyType1 overrides the Create(row) with implmentation ABC myCollection.Add(myEntity); } break; case "someType2": foreach (DataRow row in dt.Rows) { myEntity = new MyType2; myEntity.Create(row); // MyType2 overrides the Create(row) with implmentation XYZ myCollection.Add(myEntity); } break; //...etc } return myCollection; } } //(after) public class MyFactory { public ArrayList CreateCollection(DataEntity member, string type) { myCollection.Clear(); switch (type) { case "someType1": createList(new MyType1()); break; case "someType2": createList(new MyType2()); break; //etc } return myCollection; } public ArrayList createList(DataEntity mytype) { foreach (DataRow row in dt.Rows) { myEntity = (DataEntity)Activator.CreateInstance(mytype.GetType()); myEntity.Create(row); myCollection.Add(myEntity); } return myCollection; } } just refactoring, I'm sure there's a better way but this works, any suggestions on improvements gratefully recieved. Dan p.s. why does my c# code in here get so spaced out, does the same if I copy, paste or type directly in? Edited August 26, 2005 by DannyT Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.