Help with casting to a different class (upcasting?)

I don't understand something basic about classes and inheritance (or perhaps I'm just tired after hours of programming?)...

I created my own class that derived from System.Data.DataTable:

  public class MyTable : System.Data.DataTable
  { ... }

I did this because I want to carry along specific information in MyTable object that are useful to my application.

I have some database-wrapper code (let's call that myFunction()) that returns the data type System.Data.DataTable:

   System.Data.DataTable dt = myFunction();

But want I want to do is return the results of myFunction into a object of type MyTable (let's call that object mt). I thought I could do this by simply casting it as follows:

  MyTable mt = (MyTable)myFunction();

This compiles fine. And I thought this should work since MyTable is derived from DataTable. However, at runtime, I get a "Specified cast is not valid" exception at the code line above.

How can I get the System.Data.DataTable object value into my own MyTable object? Do I have to use a Copy method on the DataTable returned by myFunction?

Is what I'm trying to do called "upcasting"?

Thank you for your help.
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Gautham JanardhanCommented:
<upcasting> i dont think u can do that

u can box but not what u are trying to do here

here what u caould do

say ur CustomTable has a contructor that accepts a Datatable variable then

CustomTable Test = new CustomTable(myFunction());

ur constructor shouls handle this accordingly
i think this will be the only way
As long as myFunction is creating an instance of MyTable and MyTable is a class that derives from DataTable it works.  Can you post the relevant lines from myFunction?
Jon500Author Commented:
My code seems pretty straighforward. Here is a watered-down version that sl does not work: It get an Invalid Cast exception at the line with the ***

public void main
   ProfileList.ListDataTable ldt = EEExample();

public ProfileList.ListDataTable EEExample()
   return MyFunction();

private ProfileList.ListDataTable MyFunction()
   DataTable dt = new DataTable();
   return (ProfileList.ListDataTable)dt; //***

How can I cast the System.Data.DataTable  to my DataTable-derived class type at the line above (with the ***)?

Thank you
Cloud Class® Course: Microsoft Exchange Server

The MCTS: Microsoft Exchange Server 2010 certification validates your skills in supporting the maintenance and administration of the Exchange servers in an enterprise environment. Learn everything you need to know with this course.

You need to actually construct an instance of ListDataTable somewhere, most likely in MyFunction.  Probably something like this:

private ProfileList.ListDataTable MyFunction()
   DataTable dt = new DataTable();
   ListDataTable oLdt = new ListDataTable( dt );
   return oLdt;

And your ListDataTable class needs a constructor (i.e., a conversion operator) that accepts a DataTable.
Jon500Author Commented:
I'm sorry, bu I don't see how this helps.

Imagine (as my first example in the first message shows) that I need to call a "black box" funtion that returns a System.Data.DataTable object. I want to "import" that object instance into my ProfileList.ListDataTable data type--something I felt I should easily be able to do since my ProfileList.ListDataTable is a classed derived from System.Data.DataTable. That's why I though it should be easy to cast any System.Data.DataTable object instace to a data type of ProfileList.ListDataTable.

What is wrong with that logic?
I was trying to go by your latest code.  Your MyFunction can't return an instance of a ListDataTable unless you create one.  With this inheritance, you can treat a ListDataTable as a DataTable but not the other way around.

Your logic description falls apart when you say cast any DataTable into a ListDataTable.  A ListDataTable is a derived class, so this kind of cast is a downcast.  Meaning, it fails unless the object being cast is actually a ListDataTable.  If you want to create an instance of a ListDataTable from the DataTable, you provide a conversion operator - a constructor for ListDataTable that takes in a DataTable and constructs a new ListDataTable.
Jon500Author Commented:
OK--I suppose that I was always upcasting and not downcasting. So "downcasting" is new to me.

Are there any external resources (links) that show how to do this in practice? Are some approaches better than others? Is "downcast" the right way to describe this or are there other terms that are more widely used?

Thank you.
Jon500Author Commented:
Just one more question along the lines of the original:

If you have a framework object of type FrameWorkClass and you want to enhance objects of that type, I thought you can just use that class as a base class for a new class. For example:

class MyClass : FrameWorkClass

Now, I thought I could just create new objects like:
  MyClass oMyClass = new MyClass()

The problem is what do you do when the FrameWorkClass object already exists and you want to "import" all of its data to your newn oMyClass object???

I just don't know what doing that is called and since it's so new to me, I would appreciate a link to a tutorial or other resource that can discuss this further.

Is this not a good or common thing to be doing? Should I be taking another approach to "downcase" my object?

Thanks again!
Jon500Author Commented:
I meant "downcast" (not "downcase") my object, above.

I still need help. This question is still open. I'm just not getting what I should or shouldn't be doing to successfully downcast a derived object instance...
Jon500Author Commented:
I reviewed my code.
It seems that there is no easy way to downcast unless I use operator overloads or other undesirable strategies.

I have instead changed the idea of inheriting from DataTable. Now, I am using a public property called ListDataTable which is of type DataTable. When I have an object instance of my class, I will refer to its DataTable like this:


Casting should no longer be required because ListDataTable is indeed a Sql.Data.DataTable object instance.

Thank you for your feedback.

This issue is now closed.
Upcasting is common.  I create a dog and a cat object and put them in a collection of pets.  I upcast them to their base class pet.  No possiblity of run-time error in the upcast.

Downcast would be if I try to cast both objects in my pets collections to be dogs.  One succeeds, but the cat object won't downcast to be a dog so gives me a run-time error.  This isn't common, and many texts will say if you are downcasting you've done something wrong with your oo design.

What you're talking about is, I have a pet object and I want to turn it into a dog.  This isn't really a cast operation as it actually requires creating a new object.  I need a dog constructor that takes in a pet object and creates a dog object based on the attributes of the pet.  This is called a conversion operator as it converts the pet into a dog but creates a new object.

Sorry I don't have a tutorial link handy.  Most introductory .net books seem to have a chapter or two on basic oo fundamentals and might be a good place to start.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Jon500Author Commented:

Now that's a very good explanation. However, I have a dozen or so books on .Net/C# and cannot find this matter. In fact, the word "downcast" and "upcast" doesn't appear in any of them! (Maybe I should find a new publisher?)

I agree with one thing in particular that you wrote: that my design is likely flawed. I found that to be true and I discovered that what I really needed is only to include a DataSet class within one of my own classes--not to "inherit" it. I feel sort of dumb, but as I said I was programming late and perhaps decided to do that with only some of my synapses firing correctly.

But now that the question has been asked, I am intrigued (for academic purposes) and I do want to know more about "conversion operators". Are you talking about operator overloading that would allow my MyTable objects to be "equated" to a DataTable object? If yes, then I have plenty of resources that talk about operator overloading (something I've never needed to do). If not, then could you please clarify and even send just one Google link that touches on the subject? After that, I'll close this question.

Thanks again.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.