Solved

Help with casting to a different class (upcasting?)

Posted on 2007-03-19
12
275 Views
Last Modified: 2010-04-16
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.
0
Comment
Question by:Jon500
  • 7
  • 4
12 Comments
 
LVL 29

Assisted Solution

by:Gautham Janardhan
Gautham Janardhan earned 100 total points
ID: 18746897
<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
0
 
LVL 21

Expert Comment

by:mastoo
ID: 18748773
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?
0
 
LVL 8

Author Comment

by:Jon500
ID: 18750714
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
0
 
LVL 21

Expert Comment

by:mastoo
ID: 18750980
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.
0
 
LVL 8

Author Comment

by:Jon500
ID: 18751057
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?
0
 
LVL 21

Expert Comment

by:mastoo
ID: 18751233
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.
0
What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 
LVL 8

Author Comment

by:Jon500
ID: 18752199
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.
0
 
LVL 8

Author Comment

by:Jon500
ID: 18752427
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!
0
 
LVL 8

Author Comment

by:Jon500
ID: 18753103
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...
0
 
LVL 8

Author Comment

by:Jon500
ID: 18753191
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:

oMyClass.ListDataTable

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.
0
 
LVL 21

Accepted Solution

by:
mastoo earned 400 total points
ID: 18753254
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.
0
 
LVL 8

Author Comment

by:Jon500
ID: 18753465
Mestoo:

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.
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

In order to hide the "ugly" records selectors (triangles) in the rowheaders, here are some suggestions. Microsoft doesn't have a direct method/property to do it. You can only hide the rowheader column. First solution, the easy way The first sol…
Introduction This article series is supposed to shed some light on the use of IDisposable and objects that inherit from it. In essence, a more apt title for this article would be: using (IDisposable) {}. I’m just not sure how many people would ge…
This tutorial demonstrates a quick way of adding group price to multiple Magento products.
You have products, that come in variants and want to set different prices for them? Watch this micro tutorial that describes how to configure prices for Magento super attributes. Assigning simple products to configurable: We assigned simple products…

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now