Объясните почему возникает ошибка на этапе выполнения?
namespace CSharp
{
internal class B { }
internal class D : B { }
internal class Program
{
private static void Main()
{
Object o1 = new Object();
B b1 = new B();
D d6 = (D)b1; //System.InvalidCastException - не удалось привести тип объекта "CSharp.B" к типу "CSharp.D"
B b5 = (B)o1; //System.InvalidCastException - не удалось привести тип объекта "CSharp.Object" к типу "CSharp.B"
}
}
}
Все просто, переменная b1
ссылается на объект типа B
. Тип B
в свою очередь является базовым для типа D
, т.е. D
является производным от B
. Привести объект базового типа к более производному нельзя.
D d6 = (D)b1;
Аналогичная проблема и с этой строчкой
B b5 = (B)o1;
P.S. Небольшое замечание, если мы напишем следующий код:
B b = new D();
D d = (D)b;
и попробуем его выполнить, ошибки не будет. Здесь важно понимать следующее, что несмотря на то, что переменная b
у нас типа B
, она ссылается на объект типа D
, поэтому приведение к типу D
сработает. Т.е. строчка ниже выполнится без проблем.
D d = (D)b; // все ОК
Внимательно читаем комментарии в коде
namespace CSharp
{
//не смотря на отсутствие явного указания B является производным от Object
internal class B { }
//класс D является производным от B и как следствие от Object
internal class D : B { }
internal class Program
{
private static void Main()
{
//все варианты ниже допустимы т.к. любой класс наследуется от Object
Object o1 = new Object();//создаем базовый объект типа Object
//ниже используется неявное приведение типов
Object o2 = new B();//создаем объект типа B в переменной типа Object
Object o3 = new D();//создаем объект типа D в переменной типа Object
Иными словами, если класс B является наследником класса A, то B является частным случаем A, и обладает всеми особенностями A плюс собственные особенности.
//допустимо
B b1 = new B();
B b2 = new D();//D является производным от B
//недопустимо
B b3 = new Object();//Object не обладает всеми особенностями B
Явное приведение типов позволяет выбрать какой интерфейс объекта использовать, но не выполняет модификацию самого объекта.
//Допустимо
B b4 = (B)o2; //в переменной o2 лежит объект типа B, меняем используемый интерфейс
B b5 = (B)o3; //в переменной o3 лежит объект типа D, меняем используемый интерфейс
D d1 = (D)o3; //в переменной o3 лежит объект типа D, меняем используемый интерфейс
D d2 = (D)b2; //в переменной b2 лежит объект типа D, меняем используемый интерфейс
//не допустимо
B b6 = (B)o1; //Object не обладает всеми особенностями B
D d3 = (D)o1; //Object не обладает всеми особенностями D
D d4 = (D)o2; //B не обладает всеми особенностями D
D d5 = (D)b1; //B не обладает всеми особенностями D
}
}
}
Как меняется крипторынок и к чему готовиться владельцам криптообменников
Допустим имеется 2 шары и нужно удостоверится, что они идентичны друг другу
приветствуюпишу в WForms маленькую утилиту под windows , которая расширяет возможности буфера копирования