miked said:
I have read before that covariant return types are not necessary which I
guess is true but to get around the lack of covariant return types you have
Lost of things are in C# that are not "necessary": foreach, lock, using,
yield-return, ... and a lot more are coming in C#3.
They're dead-handy though, and so is co-variant return-types.
3 options assuming class A : B
1) Use and interface
- Klunky / Bloated / Alot of work
And, it doesn't solve any typing issues, it simply moves them.
+ None
2) public new B AProperty { get { (B)base.AProperty;} }
- Uneccesary Casting / Runtime Errors
a. The cast is not necessary for co-variant returns, it's necessary
because you have (type-wise) unexpressed knowledge that in this instance
base.AProperty should be not only A, but B.
b. A runtime-error would show that your unexpressed knowledge is false
+ Best solution if one day we get covariant return types or explicit
class member declaration
3) public override A AProperty { get { return this.BProperty; } }
public B BProperty { get { return this._bProperty } }
private B _b;
- What a mess this is and will require a lot of rewriting if covariant
return types are one day allowed.
Not to mention that A may still have storage reserved for a now unused
AProperty, all in all -- not really text-book inheritance.
Maybe MS could at least provide explicit member declarations for classes as
shown below, still messy, works like an interface without having to code an
interface just to make up for the lack of covariant return types.
public override A A.AProperty { get { return base.AProperty; } }
public B AProperty { get { return base.AProperty; } }
I'm not sure I like that very much. I think i prefer that Properties of
objects stay the same no matter what static-type I know the origin
object as, so
B b = /* some B */
A a = b;
a.AProperty == b.AProperty;
but not nessesarily:
typeof(a.AProperty) == typeof(b.AProperty)
Or... Maybe I simply don't understand OOP programming and inheritance if so
I wish someone would set me straight as I literally hit the covariant return
type wall almost every day.
I use the:
T new P { get { return (T) base.P; } }
in-between, and it works very well for me.
Be aware that this pattern requires a corresponding "set" in the
base-class is counter-variant, and should be virtual - if it exists. The
object can then verify that it's assertion on base.P.GetType() isn't
violated.
One of the reasons that co/counter-variant support isn't included is
that in order to utilize it, without making mistakes, you need to think
quite a bit.