С Новым годом! Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.78/18: Рейтинг темы: голосов - 18, средняя оценка - 4.78
1 / 1 / 0
Регистрация: 26.07.2012
Сообщений: 133

Что происходит с данными класса-наследника при таком приведении

27.09.2012, 10:03. Показов 3900. Ответов 10
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
изучал оф.мануал, рихтера и нейджела. залип вот на каком моменте:
"в С# нет специального синтаксиса для приведения типа объекта к его базовому типу, поскольку такое приведение считается безопасным неявным преобразованием"


C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class A
{
  public int a;
  public virtual void  ToStr(){Console.WriteLine("Base "+a);}
  public A(int a){this.a=a;}
}
public class B:A
{
    public int b;
    public override void  ToStr(){Console.WriteLine("Derived "+a+" "+b);}
    public B(int a,int b):base(a){this.b=b;}
}
 
class Entry
{
    public static void  Main()
    {
        A a=new A(5);
        B b = new B(10,10);
        a=b;
 
    }
}
1. Что происходит с данными класса-наследника при таком приведении? Насколько я помню в С происходило усечение класса,т.е. данные уникальных полей наследника терялись. в С# такое приведение является безопасным...т.е. данные сохраняются каким то образом и к ним можно обратиться?
И почему, собственно, обратное приведение не безопасно, тут-то данные точно не потеряются?
понимаю, вопрос туп, но что-то никак не сдвинусь.
Спасибо.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
27.09.2012, 10:03
Ответы с готовыми решениями:

Как вызвать метод дочернего класса при приведении типов?
Привет у меня есть класс (Батя) и парочка дочерних классов в классе Батя есть метод void Verefication, который унаследовали все его...

Почему при восходящем приведении типов вызывается метод класса потомка?
class T1 { public virtual void P() { Console.WriteLine(1); } } class T2 : T1 {

Что происходит с данными записанными в поток от WebClient.OpenWrite()?
Куда передаются данные из потока,при возврате потока методом OpenWrite? Что с ними происходит? class Ama { static void Main() ...

10
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
27.09.2012, 10:23
Ни в С ни в С# не происходит никаких усечений - данные как были в памяти, так там и остаются.
Разница лишь в том, что при обращении через ссылку базового класса эти данные не видно, так как базовый класс о них попросту не знает.

Цитата Сообщение от navab Посмотреть сообщение
почему, собственно, обратное приведение не безопасно
Потому что нужно точно знать к какому именно потомку производится приведение, а родитель - он и есть родитель.
0
1 / 1 / 0
Регистрация: 26.07.2012
Сообщений: 133
27.09.2012, 10:54  [ТС]
в этом случае обратиться к данным можно только через переопределенные методы?
а чем проблема при приведению к потомкам?данные родителя то они в любом случае содержат?
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
27.09.2012, 12:10
Цитата Сообщение от navab Посмотреть сообщение
в этом случае обратиться к данным можно только через переопределенные методы?
Так точно.

Цитата Сообщение от navab Посмотреть сообщение
а чем проблема при приведению к потомкам?
Проблема в том, что нужно точно знать, к какому из потомков происходит приведение, так как потомки могут быть разные. Потому компилятор не берет на себя ответственность определять, какой из потомков подразумевается, и при неявном приведении выдает ошибку.
Пример:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class A { }
class B : A { public int x; }
class C : A { public string y; }
 
void Main()
{
   A obj = GetRandomChild();
   B obj1 = obj; // откуда компилятору знать, что вернулся экземпляр класса B?
   С obj2 = obj; // откуда компилятору знать, что вернулся экземпляр класса С?
 
   B obj3 = (B)obj; // Явное приведение - на свой страх и риск. Если вернулся экземпляр класса С, то вылетит исключение в рантайме
   C obj4 = (C)obj; // Явное приведение - на свой страх и риск. Если вернулся экземпляр класса В, то вылетит исключение в рантайме
}
 
// Метод возвращает случайным образом экземпляр класса B или C
A GetRandomChild()
{
   var rand = new Random();
   if (rand.Nex(1) == 0) return new B();
   else return new C();
}
Цитата Сообщение от navab Посмотреть сообщение
данные родителя то они в любом случае содержат?
Да, данные родителя они содержат, но вот родитель данные потомков не содержит, потому неявное преобразование возможно только от потомка к родителю.
1
1 / 1 / 0
Регистрация: 07.09.2012
Сообщений: 46
03.10.2012, 00:39
kolorotur, странно почему компилятор не позволяет определить свой оператор inplisit для приведения к потомку? Можно было бы вставить проверку на is и выкидывать исключение.

Просто синтаксис стал бы намного проще...
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
03.10.2012, 10:21
Цитата Сообщение от Uletchik Посмотреть сообщение
странно почему компилятор не позволяет определить свой оператор inplisit для приведения к потомку?
Почему не позволяет? Еще как позволяет:
C#
1
2
3
4
5
6
7
8
class A
{
   public static implicit operator B(A obj)
   {
      if (obj is B) return (B)obj;
      throw new InvalidOperationException("obj is not B");
   }
}
Только это же идиотизм получается - определять операторы для потомков в базовом классе, т.к. при проектировании базового класса нужно будет знать, сколько и каких потомков у него будет, что невозможно в принципе.

А "простота" синтаксиса с большой вероятностью приведет к очень веселым ночам, проведенным в интимной обстановке с дебаггером.
1
1 / 1 / 0
Регистрация: 07.09.2012
Сообщений: 46
03.10.2012, 11:32
A мне VS 2010 пишет: "Ошибка 3: не разрешено пользовательское преобразование в базовый класс или из базового класса" ????
1
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
03.10.2012, 11:47
Да, действительно - не позволяет. Не знал, спасибо за наводку!

Оберегает, так сказать, от идиотизма
0
1 / 1 / 0
Регистрация: 07.09.2012
Сообщений: 46
03.10.2012, 12:38
Цитата Сообщение от kolorotur Посмотреть сообщение
Да, действительно - не позволяет. Не знал, спасибо за наводку!

Оберегает, так сказать, от идиотизма
Предпочитю чтоб от осмысленного идиотизма не оберегали.
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
03.10.2012, 13:46
Мне вот интересно, почему такую штуку нельзя сделать?..
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
namespace ConsoleApplication19
{
    internal class A
    {
        public int X;
 
 
        public A(int x)
        {
            X = x;
        }
    }
 
 
    internal class B : A
    {
        public B(A a) : base(a.X)
        {
 
        }
    }
 
 
    internal class Program
    {
        private static void Main()
        {
            // B b = (B) new A(1); error
            B b = new B(new A(1)); // ok
        }
    }
}
1
1 / 1 / 0
Регистрация: 07.09.2012
Сообщений: 46
03.10.2012, 14:25
Цитата Сообщение от Psilon Посмотреть сообщение
Мне вот интересно, почему такую штуку нельзя сделать?..
....
Была такая мысль, но много полей, даже ссылки копить геморойно и не эстетично и синтаксис опять корявый получается
C#
1
2
3
DeriveDeriveClass A0=new ....
DeriveDeriveClass A1=new ....
DeriveDeriveClass B= new DeriveDeriveClass(A1+A0) // оператор определенный в базовом классе и возвращающий один из более вехних классов
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
03.10.2012, 14:25
Помогаю со студенческими работами здесь

Правда, что указатель класса-наследника не может указывать на объект класса-родителя?
Доброго времени суток! Пример кода ниже. Правда ли , что указатель класса-наследника не может указывать на объект класса-родителя? ...

Ошибка при вызове метода класса-наследника
помогите не знаю что не правильно сделать выходит что в мемо выводит с класса родителя все нормально методом inform() а вот с наследника...

Что происходит когда передается в функцию базового класса аргумент с типом производного класса?
Есть функция перегруженного оператора"+" в производном классе и в базовом классе который принимает свой тип(базового класса) что...

Лишнее удаление родителя при создании класса наследника
Не могу понять откуда в выводе программы появляется первая надпись "delete A". По идее надписей "delete" должно быть столько же,...

При явном приведении к int получаются числа, но явно не те, что должны быть
Привет. Есть массив unsigned char. В него записываются данные с устройства с помощью библиотеки libusb. Изначально прибор передает...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Новые блоги и статьи
сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и источниками (напряжения, ЭДС и тока). Найти токи и напряжения во всех элементах. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru