3

Given a class hierarchy with a base class B and a subclass S:

class B { }
class S : B { }

I can assign a S to an B with an implicit conversion:

B b = new S();

If I wanted to downcast this back to a S I would have to do this explicitly:

B b = new S();
...
S s = (S)b;

Now, my understanding is we can guarantee that there is always assignment compatibility going from S to B, so we will never have to perform an explicit upcast in the following way:

S s = new S();
B b = (B)s; // or
B b2 = s as B;

Is this assertion correct, or as the question states Do I Ever Have to Perform An Explicit Upcast?

Jon Egerton
  • 40,401
  • 11
  • 97
  • 129
James Wiseman
  • 29,946
  • 17
  • 95
  • 158
  • If you are intentionally upcasting objects anywhere in your codebase, I guess you'd be breaking the Liskov Substitution Principle by definition. – MarioDS Oct 26 '17 at 09:49

2 Answers2

4

You might do with interfaces, if the class has got an explicit implementation:

interface I {
    void Method();
}

class C : I {
    void I.Method() { ... }
}

C c = new C();
c.Method();      // won't compile
((I)c).Method(); // have to cast to I first
thecoop
  • 45,220
  • 19
  • 132
  • 189
3

If you have

class B { }
class S : B { }
class T : B { }

and you try to do something like

var b = myBool ? new S() : new T();

this won't compile unless you explicitly cast either the S or the T instance (or both) to B.

The same goes for anonymous methods; this

new bool[0].Select(b => 
    { if (b) { return new S(); } else { return new T(); } });

won't compile without casts (or specifying Select<bool, B> but this might not be possible, for example if your source is an anonymous type).

Also, if you have

class B { public void DoSomething() { } }
class S : B { public new void DoSomething() { } }

then

S s = new S();
s.DoSomething();       // calls the S version
((B)s).DoSomething();  // calls the B version
Rawling
  • 49,248
  • 7
  • 89
  • 127
  • I'm not sure about calling the base version with a cast, I thought it might be the case but went to investigate and it [seems it's not](http://stackoverflow.com/questions/437926/force-calling-the-base-method-from-outside-a-derived-class) – James Oct 25 '12 at 09:43
  • @JamesB It doesn't work for virtual methods, but it does for methods hidden by `new`. – Rawling Oct 25 '12 at 09:44
  • Accepted! For sending me on an interesting tagent. – James Wiseman Oct 25 '12 at 11:57