views:

74

answers:

5

Hello all,

I need to outline a little bit of background info for context. Please bear with me and I'll try to simplify my question as much as possible:

I have one object that inherits from another object. We'll call the first object Fruit and the second Apple. So I've declared Apple as follows:

public class Apple : Fruit
{
    public string appleType;
    public string orchardLocation;
    // etc.
}

And the Fruit object as follows:

public class Fruit
{
    public int fruitID;
    public int price;
    // etc.
}

So Apple inherits from Fruit. And let's say I have a number of other fruit types that all inherit from Fruit: Banana, Orange, Mango, etc.

In my application, I maintain the ability to store a particular type of fruit in the Session as that type's object, so I may have an Apple object in there or a Banana object. And I have a method that will retrieve the current Fruit from the session, written as follows:

protected Fruit GetModel(int fruitID)
{
   // code to retrieve the fruit from the Session
   // fruitID could be the ID for an Apple or Banana, etc.
}

Occasionally, I have a need to pull the fruit from the Session, update something about it, then upload it back into the Session. I may do this like this:

Apple myApple = (Apple)GetModel(fruitID);
myApple.orchardLocation = "Baugers";
UpdateModel(myApple); // just overwrites the current fruit in the Session

Now my question. I'm at a point where I need to pull the object from the Session, update something specific to the fruit itself (say, price), and then upload that same object back into the Session. Until now, I've always known the type of the object, so in my case now -- if I knew the fruit type -- I could just say:

Apple myApple = (Apple)GetModel(fruitID);
myApple.price = "4";
UpdateModel(myApple);

But this time, I'm trying to make it more generic to Fruit itself and don't always know the child type. And if I try to just pull the Fruit object itself from the Session (without casting), update it, and upload it back in, I've now just lost my child object (Apple) and only have a Fruit object in the Session. So I need a way to, generically, create a new instance of the type of object in the Session, update it, then upload it back in.

I know of a .NET method for Object called GetType() that returns a System.Type of the type of object you call it on, assuming that object inherits from Object. But I wasn't able to get very far with this, and I'd prefer not to have Fruit inherit from Object.

So I'll end with a pseudocode version of what I'd like:

public updateModelPrice(int price, fruitID)
{
    FigureOutType fruit = (FigureOutType)GetModel(fruitID);
    fruit.price = price;
    UpdateModel(fruit);
}

Any help would be very much appreciated. Thanks.

A: 

If you don't know if it's a Banana or Apple at run-time what will you be able to do with the Fruit object.

Apple myApple = (Apple)GetModel(fruitID);

You must know,it's an apple to do anything related to Apple object,so you must cast the Fruit object to type Apple.

May be you can try updating your UpdateModelmethod to dealwith the Fruit type.

this. __curious_geek
+5  A: 

Since price is a member of Fruit, you don't need to figure out the subtype. You can just do this:

public updateModelPrice(int price, fruitID)
{
    Fruit fruit = GetModel(fruitID);
    fruit.price = price;
    UpdateModel(fruit);
}
Jeff Sternal
the problem is that I want to maintain the Apple object in the Session, with all its Apple properties. If I cast the object to just a Fruit, then upload that back into the Session, I've now lost my Apple properties; all I have is a Fruit object in the session
Mega Matt
@Matt: see my answer; even if you have the apple boxed as a `Fruit`, you can still get it back to an `Apple` by testing using `is` to find out what it is and casting it back. Your `Apple` is still an `Apple` - it does not change into a `Fruit`, only is used as one.
Callum Rogers
@Matt - casting an object instance doesn't change the type of the underlying instance: it's still an `Apple` and in other parts of your code, you can still treat the instance as an `Apple` by casting it again.
Jeff Sternal
@Jeff `GetModel` in the question was declared to return `Fruit` so you don't need the cast in your example.
Phil Ross
@Phil - whoops, fixed. Thank you!
Jeff Sternal
@Meta Matt: "the problem is that I want to maintain the Apple object in the Session, with all its Apple properties. If I cast the object to just a Fruit, then upload that back into the Session, I've now lost my Apple properties" -- so is that what happened when you actually *tried* it, or are you just guessing ;) Go ahead, try the code in this answer, you'll be pleasantly surprised that you don't "lose" any information about your object by referring to it by its parent type.
Juliet
Well I have to admit you're all right. I assume this is because of C#'s pointers? Thanks very much for the help!
Mega Matt
A: 

You could use the is keyword to determine the actual type of the Fruit at runtime:

if(fruit is Apple)
    DoAppleStuff();
else if(fruit is Orange)
    Orange o = (Orange)fruit;

// etc
Callum Rogers
+1  A: 

A simple test should do it

if(obj is Apple)

Where obj is the object and Apple is the type you're testing

And by the way every class you create inherits from object

Rune FS
A: 

Try this:

public void updateFruitModel<T>(int price, int fruitId) where T : Fruit
{
    T fruit = (T)GetModel(fruitId);
    fruit.price = price;
    UpdateModel(fruit);
}
Wesley Wiser
and I call it like `updateFruitModel<"Apple">(4, 28);` ?
Mega Matt