web-dev-qa-db-fra.com

downcast et upcast

Je suis nouveau sur C # (et [~ # ~] oop [~ # ~] ). Quand j'ai du code comme celui-ci:

class Employee
{
    // some code
}


class Manager : Employee
{
    //some code
}

Question 1: Si j'ai un autre code qui fait ceci:

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

Ici Employee est un Manager, mais quand je le jette comme ça sur un Employee, cela veut dire que je l’incruste?

Question 2:

Quand j'ai plusieurs objets de classe Employee et que certains, mais pas tous, sont des objets Manager, comment puis-je les réduire autant que possible?

80
user184805
  1. C'est correct. Lorsque vous faites cela, vous le créez dans un objet employee, ce qui signifie que vous ne pouvez accéder à aucun élément spécifique à un gestionnaire.

  2. Le downcasting est l'endroit où vous prenez une classe de base, puis essayez de la transformer en classe plus spécifique. Ceci peut être accompli avec using is et une distribution explicite comme ceci:

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

ou avec l'opérateur as comme ceci:

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

Si quelque chose n'est pas clair, je serai heureux de le corriger!

82
RCIX

pcasting (en utilisant (Employee)someInstance) est généralement facile car le compilateur peut vous dire lors de la compilation si un type est dérivé d’un autre.

Downcasting doit cependant être fait au moment de l'exécution car le compilateur peut ne pas toujours savoir si l'instance en question est du type indiqué. C # fournit deux opérateurs pour cela - is qui vous indique si le downcast fonctionne et renvoie true/false. Et as qui tente d'effectuer la conversion et renvoie le type correct si possible, ou null si ce n'est pas le cas.

Pour tester si un employé est un manager:

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");

Vous pouvez aussi utiliser ceci

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");
47
Preet Sangha
  • pcasting est une opération qui crée une référence de classe de base à partir d'une référence de sous-classe. (sous-classe -> superclasse) (i.e. Manager -> Employee)
  • Downcasting est une opération qui crée une référence de sous-classe à partir d'une référence de classe de base. (superclasse -> sous-classe) (c.-à-d. employé -> gestionnaire)

Dans ton cas

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

vous faites un upcasting.

Un upcast réussit toujours, contrairement à un downcast qui requiert une conversion explicite, car il peut potentiellement échouer à l'exécution. ( InvalidCastException ).

C # propose à deux opérateurs d'éviter cette exception:

A partir de:

Employee e = new Employee();

Première:

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

Seconde:

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

Attention: Lorsque vous effectuez un upcast, vous ne pouvez accéder qu'aux méthodes, propriétés, etc. de la superclasse.

9
overcomer

Si vous devez vérifier si chaque objet Employé est un objet Gestionnaire, utilisez la méthode 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..
}
6
HOKBONG

Réponse 1: Oui, cela s’appelle upcasting, mais la façon dont vous le faites n’est pas moderne. La diffusion en amont peut être effectuée implicitement, aucune conversion n'est nécessaire. Il suffit donc d’écrire Employee emp = mgr; est suffisant pour la conversion ascendante.

Réponse 2: Si vous créez un objet de la classe Manager, nous pouvons dire que ce gestionnaire est un employé. Parce que gestionnaire de classe: Employé représente relation Est-A entre la classe Employé et la classe Gestionnaire. On peut donc dire que chaque manager est un employé.

Mais si nous créons un objet de la classe Employee, nous ne pouvons pas dire que cet employé est manager car class Employee est une classe qui n'hérite d'aucune autre classe. Vous ne pouvez donc pas directement abaisser cet objet Employee Class en objet Manager Class.

Donc, la réponse est que, si vous voulez passer de l’objet Employee Class à l’objet Manager Class, vous devez d’abord avoir l’objet de Manager Class, puis vous pouvez le convertir en amont, puis vous pouvez le baisser.

0
Asad Patel