Eu sou novo em C # (e OOP ). Quando tenho algum código como o seguinte:
class Employee
{
// some code
}
class Manager : Employee
{
//some code
}
Pergunta 1 : se eu tiver outro código que faça isso:
Manager mgr = new Manager();
Employee emp = (Employee)mgr;
Aqui Employee
está um Manager
, mas quando o lancei assim para um Employee
, significa que o estou rejeitando?
Questão 2 :
Quando eu tenho vários Employee
objetos de classe e alguns, mas não todos, são Manager
, como posso fazer o downcast deles quando possível?
Employee emp= mgr;
deve ser suficiente.Respostas:
Está correto. Ao fazer isso, você o está convertendo em um
employee
objeto, o que significa que não pode acessar nada específico do gerenciador.Downcasting é quando você pega uma aula básica e tenta transformá-la em uma aula mais específica. Isso pode ser feito usando is e um elenco explícito como este:
if (employee is Manager) { Manager m = (Manager)employee; //do something with it }
ou com a
as
operadora assim:Manager m = (employee as Manager); if (m != null) { //do something with it }
Se algo não estiver claro, terei todo o gosto em corrigi-lo!
fonte
as
operador em vez deis
, seguido por uma conversão.O upcasting (usando
(Employee)someInstance
) é geralmente fácil, pois o compilador pode informar em tempo de compilação se um tipo é derivado de outro.No entanto, o downcasting deve ser feito em tempo de execução, pois o compilador nem sempre pode saber se a instância em questão é do tipo fornecido. C # fornece dois operadores para isso - é que lhe diz se as obras baixos, e retornar verdadeiro / falso. E as que tenta fazer a conversão e retorna o tipo correto, se possível, ou nulo, se não.
Para testar se um funcionário é um gerente:
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");
Você também pode usar este
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");
fonte
No seu caso
Employee emp = (Employee)mgr; //mgr is Manager
você está fazendo um upcasting.
Um upcast sempre é bem-sucedido, ao contrário de um downcast que requer uma conversão explícita porque pode falhar potencialmente em tempo de execução ( InvalidCastException ).
C # oferece dois operadores para evitar que essa exceção seja lançada:
Começando de:
Employee e = new Employee();
Primeiro:
Manager m = e as Manager; // if downcast fails m is null; no exception thrown
Segundo:
if (e is Manager){...} // the predicate is false if the downcast is not possible
Aviso : Quando você faz um upcast, você só pode acessar os métodos da superclasse, propriedades etc ...
fonte
Caso você precise verificar se cada um dos objetos Employee é um objeto Manager, use o método 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.. }
fonte
Resposta 1: Sim, é chamado de upcasting, mas a maneira como você faz isso não é moderna. O upcasting pode ser executado implicitamente, você não precisa de nenhuma conversão. Então, basta escrever Employee emp = mgr; é o suficiente para upcasting.
Resposta 2: Se você criar um objeto da classe Manager, podemos dizer que o gerente é um funcionário. Porque a classe Manager: Employee descreve o relacionamento Is-A entre a Classe de Funcionário e a Classe de Gerente. Portanto, podemos dizer que todo gerente é um funcionário.
Mas se criarmos um objeto da classe Employee não podemos dizer que esse funcionário é gerente porque a classe Employee é uma classe que não está herdando nenhuma outra classe. Portanto, você não pode reduzir diretamente esse objeto de Classe de Funcionário para o objeto de Classe de Gerente.
Portanto, a resposta é: se você deseja fazer o downcast do objeto da Classe de Funcionário para o objeto da Classe de Gerente, primeiro você deve ter o objeto da Classe de Gerente primeiro, depois pode fazer o upcast dele e depois fazer o downcast dele.
fonte
Upcasting e Downcasting:
Upcasting: Casting de Classe Derivada para Classe Base Downcasting: Casting de Classe Base para Classe Derivada
Vamos entender o mesmo como exemplo:
Considere duas classes Shape como minha classe pai e Circle como uma classe derivada, definidas da seguinte maneira:
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; } }
Upcasting:
Forma s = nova forma ();
Círculo c = s;
Ambos c e s estão referenciando o mesmo local de memória, mas ambos têm visualizações diferentes, ou seja, usando a referência "c" você pode acessar todas as propriedades da classe base e classe derivada também, mas usando a referência "s" você pode acessar as propriedades da única classe pai.
Um exemplo prático de upcasting é a classe Stream, que é a classe base de todos os tipos de leitor de stream da estrutura .net:
Leitor StreamReader = novo StreamReader (novo FileStreamReader ());
aqui, FileStreamReader () é atualizado para streadm reder.
Downcasting:
Forma s = novo círculo (); aqui, como explicado acima, a visão de s é o único pai, a fim de torná-lo para ambos, pai e filho, precisamos diminuir
var c = (círculo) s;
O exemplo prático de Downcasting é a classe de botão do WPF.
fonte