I have a base class, and I have a property of that base class that I need.
It obviously works fine returning that base class, the problem is that it will also downcast any other class that’s overriding it due to it return the base class…
Properties cannot be generic and I don’t want to upcast every single time I call this function manually
My question is… is there any way to upcast a type without know the specific type?
It sounds unclear… so I’ll give an example:
Imagine having the base class A
and two children classes B and C
A has a proerpty (called ‘Value’ for that example) that returns an A type that relates to that specific object in some way
if I replace all the A’s with B’s or C’s, for different uses
How can I do b.Value and instead of getting an A type object get an upcasted version (if possible) to a B type object, and if I do c.Value it’ll work the same way for C?
if It’s confusing please let me know so I can try to explain better
If you need the specific child type, what’s the point of using inheritance here? If you have a “B” reference to a B object (rather than an A reference), then you can just call a property specific to B, like B.BValue.
I’ll give a pseudo-code example to see if I understand your situation.
public class BaseTypeA
{
public BaseType Value { get; set; }
}
public class ChildTypeB : BaseTypeA
{
public int SomeValueB { get; set; }
}
public class ChildTypeC : BaseTypeA
{
public int SomeValueC { get; set; }
}
And you want it so that if you have a variable typed as BaseTypeA, and you access ‘Value’, it’ll be cast to the ChildType respective to it?
BaseType obj = new ChildTypeB();
obj.Value.SomeValueB = 5;
???
If so, no, you can’t do that directly.
Now there are designs I could think of that might get something close to this (like a generic base class that takes in a T for the property ‘Value’, and the base class is abstract. Or using the ‘new’ keyword to overwrite the property on the child class. But all of these require ‘obj’ to be cast as the child type, not as the base type).
Thing is… this sounds like a really weird design.
Which leads me to the question of:
What are you trying to accomplish? Not what code you want to write, but rather what you expect to accomplish with such code?
…
How about you do this. Show us the code you want to write, using the class names/use case with it. I get it won’t compile, but just write it out and post it here. So we can see the actual use in action that you expect.
I tried something like this once, if I’m reading this right. I had “blueprints” – unchanging data about types of objects: C_BP inherited from B_BP inherited from A_BP. Real objects were the same: C from B from A. Every real A/B/C object had a link to it’s blueprint. A B linked to a B_BP. and so on. I just put “A_BP myBlueprint;” in the base class (which could be used to point to any blueprint of any type).
It worked fine. But I think it had that same quirk. Sure, B’s could get their blueprint, and it was a B_BP object, but it was stored in an A_BP. It seemed as if there should be a nicer was to enforce that and auto-cast.
I think I gave up on an elegant solution – maybe I just overloaded getMyBlueprint() functions that did the casting. I don’t think I’d even subclass them like that, now (it was something like ThingThatCanBeDamaged, ThingThatCanShoot, ThingThatCanShootAndMove. I was trying to give proper OOP a chance).
I use proper OOP in here because I made a base tree structure which I wanna expend for several uses… I wanna get the parent casted already… so if Im using the base class it will return the base class, however if I use a certain expention of it, it will return an upcasted (if possible) version of the parent
It sounds like your situation is something like this:
class Alpha {
public virtual Alpha GetValue()
{ return (something of type Alpha); }
}
class Beta : Alpha {
public override Alpha GetValue()
{ return (something of type Beta); }
}
class Gamma : Alpha {
public override Alpha GetValue()
{ return (something of type Gamma ); }
}
void SomeFunction(Beta myBeta)
{
// You want to be able to eliminate the words "as Beta" from this line:
Beta otherBeta = myBeta.GetValue() as Beta;
}
Caveat: I’m not sure why Gamma supposedly matters to this example. (?) If you don’t know whether you’ve got a Beta or a Gamma, then you can’t declare the appropriate type of variable to store it in, so having a more-specific return type wouldn’t help you even if it were somehow possible.
If that’s correct, this sounds like one of the rare cases where you want to use method hiding. You might rewrite this to something like:
class Alpha {
public Alpha GetValue()
{ return GetValueInternal(); }
protected virtual Alpha GetValueInternal()
{ return (something of type Alpha); }
}
class Beta : Alpha {
public new Beta GetValue()
{ return (something of type Beta); }
protected override Alpha GetValueInternal()
{ return (something of type Beta); }
}
void SomeFunction(Beta myBeta, Alpha myAlpha)
{
// The "new" keyword hides Alpha's implementation of GetValue() when the STATIC type
// of the variable is Beta, which saves you from having to write a cast
Beta otherBeta = myBeta.GetValue();
// If the variable is of type Alpha, then the computer calls Alpha's
// definition of GetValue, so we need the cast again.
Beta thirdBeta = myAlpha.GetValue() as Beta;
}