удрученный и удрученный - PullRequest
77 голосов
/ 06 октября 2009

Я новичок в C # ООП ). Когда у меня есть код, подобный следующему:

class Employee
{
    // some code
}


class Manager : Employee
{
    //some code
}

Вопрос 1 : Если у меня есть другой код, который делает это:

   Manager mgr = new Manager();
   Employee emp = (Employee)mgr;

Здесь Employee - это Manager, но когда я преобразую его таким образом в Employee, это означает, что я его выгружаю?

Вопрос 2 :

Когда у меня есть несколько Employee объектов класса, и некоторые, но не все из них Manager, как я могу уменьшить их, где это возможно?

Ответы [ 6 ]

80 голосов
/ 06 октября 2009
  1. Это правильно. Когда вы делаете это, вы преобразуете его в объект employee, что означает, что вы не можете получить доступ к чему-либо конкретному менеджеру.

  2. В Downcasting вы берете базовый класс, а затем пытаетесь превратить его в более конкретный класс. Это может быть достигнуто с использованием is и явным приведением типа этого:

    if (employee is Manager)
    {
        Manager m = (Manager)employee;
        //do something with it
    }
    

или с оператором as, например:

Manager m = (employee as Manager);
if (m != null)
{
    //do something with it
}

Если что-то неясно, я буду рад исправить это!

47 голосов
/ 06 октября 2009

Upcasting (с использованием (Employee)someInstance) обычно легко, так как компилятор может сообщить вам во время компиляции, является ли тип производным от другого.

Даункастинг однако должен выполняться во время выполнения, так как компилятор может не всегда знать, относится ли рассматриваемый экземпляр к указанному типу. C # предоставляет два оператора для этого - is , который сообщает вам, работает ли downcast, и возвращает true / false. И как , который пытается выполнить приведение и возвращает правильный тип, если это возможно, или ноль, если нет.

Чтобы проверить, является ли работник менеджером:

Employee m = new Manager();
Employee e = new Employee();

if(m is Manager) Console.WriteLine("m is a manager");
if(e is Manager) Console.WriteLine("e is a manager");

Вы также можете использовать это

Employee someEmployee = e  as Manager;
    if(someEmployee  != null) Console.WriteLine("someEmployee (e) is a manager");

Employee someEmployee = m  as Manager;
    if(someEmployee  != null) Console.WriteLine("someEmployee (m) is a manager");
9 голосов
/ 28 сентября 2015
  • Upcasting - это операция, которая создает ссылку на базовый класс из ссылки на подкласс. (подкласс -> суперкласс) (т. е. менеджер -> сотрудник)
  • Downcasting - это операция, которая создает ссылку на подкласс из ссылки на базовый класс. (суперкласс -> подкласс) (т. е. сотрудник -> менеджер)

В вашем случае

Employee emp = (Employee)mgr; //mgr is Manager

вы делаете апскейтинг.

Передача всегда успешна, в отличие от понижения, для которого требуется явное приведение, потому что оно потенциально может дать сбой во время выполнения ( InvalidCastException ).

C # предлагает два оператора для исключения этого исключения:

Начиная с:

Employee e = new Employee();

Первый:

Manager m = e as Manager; // if downcast fails m is null; no exception thrown

Во-вторых:

if (e is Manager){...} // the predicate is false if the downcast is not possible 

Предупреждение : Когда вы делаете upcast, вы можете получить доступ только к методам, свойствам и т. Д. Суперкласса ...

6 голосов
/ 22 января 2014

Если вам нужно проверить каждый объект Employee, является ли он объектом Manager, используйте метод OfType:

List<Employee> employees = new List<Employee>();

//Code to add some Employee or Manager objects..

var onlyManagers = employees.OfType<Manager>();

foreach (Manager m in onlyManagers) {
  // Do Manager specific thing..
}
0 голосов
/ 03 мая 2019

Ответ 1: Да, это называется апкастинг, но то, как ты это делаешь, не современно. Обновление может быть выполнено неявно, вам не нужно никакого преобразования. Так что просто пишите Сотрудник emp = mgr; достаточно для апскейтинга.

Ответ 2: Если вы создаете объект класса Manager, мы можем сказать, что manager - это сотрудник. Потому что Менеджер класса: Сотрудник изображает Is-A отношение между Классом сотрудника и Классом менеджера. Таким образом, мы можем сказать, что каждый менеджер является сотрудником.

Но если мы создаем объект класса Employee, мы не можем сказать, что этот сотрудник является менеджером, потому что class Employee - это класс, который не наследует какой-либо другой класс. Таким образом, вы не можете напрямую перевести этот объект класса Employee в объект класса Manager.

Так что ответ таков: если вы хотите понизить класс объекта «Сотрудник» до класса «Менеджер», сначала вы должны сначала получить объект класса «Менеджер», затем вы можете вывести его из списка, а затем уменьшить его.

0 голосов
/ 26 января 2018

Upcasting и Downcasting:

Upcasting: кастинг из производного класса в базовый класс Даункинг: каст из базового класса в производный класс

Давайте разберемся так же, как пример:

Рассмотрим два класса Shape как Мой родительский класс и Circle как Производный класс, определенный следующим образом:

class Shape
{
    public int Width { get; set; }
    public int Height { get; set; }
}

class Circle : Shape
{
    public int Radius { get; set; }
    public bool FillColor { get; set; }
}

Приведение к базовому типу:

Shape s = новая форма ();

Круг c = s;

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

Практическим примером upcasting является класс Stream, который является базовым классом всех типов потоковых ридеров .net framework:

StreamReader reader = новый StreamReader (новый FileStreamReader ());

здесь FileStreamReader () преобразуется в стред-ридер.

понижающее приведение:

Shape s = новый круг (); здесь, как объяснено выше, представление s является единственным родителем, чтобы сделать его как для родителя, так и для ребенка, нам нужно уменьшить его

var c = (Круг) с;

Практическим примером Downcasting является класс кнопок WPF.

...