This is a very basic question, yet a very, very important one. But I'm not sure this site is the best medium for getting your answer (and more importantly, for understanding it). Try to take a lesson in OOP somewhere, or look for an online presentation detailing it.
Short answer
Runtime type and Static type are two very different things.
Longer answer:
In a statically typed language as C# (or java, or F#, or a bunch of others), a variable always has a static type. The static type is the type that the compiler proved the variable is of, because you told it it is, or because it inferred it (in case of var or lambda arguments for instance).
Some exemples:
int i; //i is of type int
BaseClass b; //b is of class BaseClass
IEnumerable<int> list; //list implements interface IEnumerable<int>
var s = "foo"; //s is inferred to be of type string
This is static typing. It means the variable is of the given type. It does not mean that the object in the variable is this type (which would not even make sense for an interface!), it just means that the compiler has proof that the object inside is assignable to this type (which exactly means it can be put into a variable/field of that type).
Contrast the runtime type. The runtime type is the actual type of the instance. It's only a runtime thing, the compiler cannot access it. It is what is effectively there.
When you statically make method and property calls, you can only call properties and methods from the static type. Simply because it's the only type the compiler can know about. When you're writing
BaseInterface bi= new Child();
You're effectively telling the compiler "I ask you to forget this object is a Child
, treat it as a BaseInterface
". And that's exactly what the compiler does: you cannot access bi's member that are specific to the Child
class.
In fact, this assignation is just a short way to make two very different operations. It's the same as
BaseInterface bi; // I create a "bi" variable. Its static type is BaseInterface
bi = new Child() // Instanciate an object of runtime type Child and assign it to the bi variable
Assigning a value to the variable does not the change its static type.