2

How to downcast with strongly runtime known type ?

public class A {}

public class B : A { public int i; }

public class C
{
    B b = new B();
    A a = b;               // here upcast, and "a" still keeps link to "b"
    ((B)a).i;              // no problem it works

    Type t = b.GetType();  // BUT how to downcast with strongly runtime known type ?
    ((t)a).i;              // like here
}
Peter B
  • 22,460
  • 5
  • 32
  • 69
noob
  • 21
  • 2
  • There’s several casting syntaxes out there: var a = (A)b; var a = (b as A); – James LoForti Jan 13 '20 at 13:41
  • 1
    Since the compiler doesn't know what `t` is, it doesn't know whether the member `i` exists or not. If you are fine without compile time checking of members, then you can try `dynamic`... – Sweeper Jan 13 '20 at 13:41
  • Type Casting using `((t)a)` requires that `t` is known at compile time, before the program runs. In this code `t` clearly isn't known at compile time because it is a variable that gets its value at runtime. – Peter B Jan 13 '20 at 13:49

1 Answers1

5

The problem with any runtime conversion, such as using Convert.ChangeType, you will only get back object which means you wont be able to do anything useful (such as set a property) without using reflection.

One possibility for "I dont know the type, but I'm confident I can set a given property" is the use of dynamic:

B b = new B();
A a = b; 
dynamic x = a;
x.i = 100;
Console.WriteLine(b.i); /// writes 100.

Live example: https://rextester.com/WJDQQ44845

Note this shows an appropriate error if you try to call a property/method which does not exists:

x.nosuchproperty =  100;

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'Rextester.B' does not contain a definition for 'nosuchproperty'

Jamiec
  • 133,658
  • 13
  • 134
  • 193