The_Unknown_Member Ответов: 6

[C#] вопрос о полиморфизме


Привет. Я начинаю путаться с этим:
using System;

namespace CSharp_Practicing
{
    class Program
    {
        static void Main()
        {
            Person p = new Student(); // Here in this line im getting confused. I am making a reference of type Person and making this reference point to the Student constructor right ? 
            p = p as Student; // In this line im doing a cast to Student but still cant access the ID property
            
        }
    }

    class Person
    {
        public int Age { get; set; }
        public string Name { get; set; }
    }

    class Student : Person
    {
        public int ID { get; set; }
    }
}


Что я уже пробовал:

Ищу информацию в интернете, но не могу найти объяснения этому.

6 Ответов

Рейтинг:
2

RickZeeland

Я думаю, когда ты это сделаешь:

Person p = new Student();
вы свободный идентификатор, как в лицо, так что вы должны использовать:
Student p = new Student();


Richard Deeming

Технически это не так терять удостоверение личности; вы просто не можете его увидеть, потому что во время компиляции тип переменной не имеет свойства ID.

То время выполнения тип переменной по-прежнему Student, и удостоверение личности все еще там. :)

Рейтинг:
2

AnotherKen

Персона Р = новый студент();

Должно быть Student p = new Student (); это создаст экземпляр объекта типа Student, который наследует свойства Person и реализует свойство ID.

p = p как студент; этот типаж не является необходимым.

теперь вы можете получить доступ к идентификатору с помощью p.ID


The_Unknown_Member

Я знаю, что. Но я изучаю полиморфизм

Рейтинг:
2

Richard Deeming

Person p;
объявляет новую переменную с во время компиляции типа Person.

Он может содержать любой объект типа Person, или любого типа, производного от Person В результате компилятор позволит вам получить доступ только к членам, определенным на Person тип или его базовые типы.

p = new Student();
создает новый экземпляр Student класс, и хранит его в p переменная.

Это работает, потому что Student класс наследуется от Person класс. Один Student это Person.

Переменная теперь имеет время выполнения типа Student... Но ... во время компиляции тип еще есть Person.

Компилятор не позволит вам получить доступ к ID свойство, потому что оно не определено на Person класс или один из его базовых классов. Компилятор понятия не имеет, каким будет тип переменной во время выполнения и будет ли она иметь ID собственность.

p = p as Student;
принимает значение, хранящееся в p, и пытается привести его к Student пример. Если это удастся, то значение будет помещено обратно в переменную p. Если это не удается, переменная p будет установлено значение null.

Но тип времени компиляции p не измениться. Вы все еще не можете получить доступ к ID свойство, потому что компилятор понятия не имеет, существует ли оно вообще.


Есть различные способы получить доступ к собственности:
Student s = p as Student;
int id = s == null ? 0 : s.ID;

int id = (p as Student)?.ID ?? 0; // Shorter version of the previous code.

int id = ((Student)p).ID; // Throws an exception if p is not a Student.

dynamic d = p;
int id = d.ID; // Throws an exception if p does not have a public readable
               // "ID" property that can be converted to an int.
               // Also much slower than the other options.


Рейтинг:
1

W∴ Balboos, GHB

Person p = new Student();
По-видимому, это несоответствие типов: объект Person не может содержать объект Student.

Он не может удержаться p.ID как члену клуба для этого нет места.

Рассмотрим, есть ли у вас объект типа Point (), который является целочисленной парой (x, y) в качестве членов.
int q = new Point();  // makes no sense.  Does q hold x or y


Richard Deeming

"объект Person не может содержать объект Student"

За исключением того, что он может: Student наследует от Person, так что совершенно справедливо поставить Student экземпляр в Person переменная.

Рейтинг:
1

David_Wimbley

Вы пытаетесь назначить p типа Person в качестве студента, даже если его тип по-прежнему Person, который не содержит свойства Id.

Вам нужно объявить свое приведение в качестве студента к новой переменной, скажем "студент".

Экс:

Person p = new Student();
        
        // still of type Person so cannot access Id since there is no Id on class Person
        p = p as Student;

        Student student = p as Student;
        var studentId = student.Id;


The_Unknown_Member

объясните мне эту строку кода:
Студент студент = p как студент; < -------------

David_Wimbley

Итак, у вас есть класс ученика и человека. Человек считается базовый класс и студент ваш дочерний класс, который наследует от человека.

Ваша проблема, я думаю, в том, что вы путаете, что такое родительский/базовый класс. Вы пытаетесь получить доступ к свойству из своего дочернего класса (Student), объявив переменную в качестве базового типа класса (Person). Если вы хотите получить доступ к свойству name/age от student, которые являются свойствами базового класса, вы можете сделать это, но вы не можете отменить этот процесс, поскольку вы не можете получить доступ к свойствам дочернего класса из базового класса.

Строка, которую вы выделяете, объявляет переменную типа Student, и вы записываете свою переменную Person (p) как тип Student

Рейтинг:
0

AnotherKen

Как вы хотите использовать полиморфизм? Например, вы уже перегружаете оператор присваивания, чтобы иметь возможность устанавливать и получать значения свойств для объектов Person и Student с помощью"=". Если вы также хотите перегрузить оператор присваивания, чтобы позволить вам сделать что-то вроде Person a = Student b, то вам придется самому предоставить логику для этого.