abattu et upcast

88

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 cela:

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

Voici Employeeun Manager, mais quand je le lance comme ça sur un, Employeecela signifie que je le upcast

Question 2 :

Quand j'ai plusieurs Employeeobjets de classe et que certains mais pas tous sont Managerdes objets , comment puis-je les réduire si possible?

user184805
la source
6
L'upcasting peut être effectué sans diffusion explicite. Cela Employee emp= mgr;devrait donc suffire.
embrasse mon aisselle le

Réponses:

93
  1. C'est correct. Lorsque vous faites cela, vous le convertissez en un employeeobjet, ce qui signifie que vous ne pouvez accéder à rien de spécifique au gestionnaire.

  2. Downcasting est l'endroit où vous prenez une classe de base, puis essayez de la transformer en une classe plus spécifique. Cela peut être accompli en utilisant is et un cast explicite comme celui-ci:

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

ou avec l' asopérateur 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!

RCIX
la source
J'ai besoin d'un exemple pour savoir ce qu'est le Downcasting?
user184805
4
Évitez de redéfinir des termes bien établis: «boxing», dans le contexte de la POO et du C #, signifie quelque chose d'assez différent (= envelopper un objet de type valeur dans une référence). De plus, votre exemple pourrait (et devrait) utiliser l' asopérateur à la place de is, suivi d'un cast.
Konrad Rudolph
2
Je suis corrigé sur le premier point, et j'ai changé la seconde moitié de ma réponse pour montrer les deux façons de le faire.
RCIX
2
Votre première déclaration ("... convertir [une instance de la classe Manager] en un objet" employé "[..] signifie que vous ne pouvez accéder à rien de spécifique au manager") n'est pas complètement exacte. Dans l'exemple d'OP, si Employee a un membre virtuel qui est remplacé dans Manager, le CLR appellera l'implémentation Manager, nonobstant la distribution. Extrait de l'article MSDN sur le polymorphisme en C #: "Lorsqu'une classe dérivée remplace un membre virtuel, ce membre est appelé même lorsqu'une instance de cette classe est en cours d'accès en tant qu'instance de la classe de base." L'exemple fourni par MSDN est presque identique.
Antony
49

L'upcasting (utilisation (Employee)someInstance) est généralement facile car le compilateur peut vous dire au moment de la compilation si un type est dérivé d'un autre.

Le downcasting cependant doit être fait au moment de l'exécution en général car le compilateur peut ne pas toujours savoir si l'instance en question est du type donné. C # fournit deux opérateurs pour cela - est qui vous indique si le downcast fonctionne et renvoie true / false. Et comme qui tente de faire le cast et renvoie le type correct si possible, ou null sinon.

Pour tester si un employé est un gestionnaire:

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 également 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");
Preet Sangha
la source
11
  • L'upcasting 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) (ie Manager -> Employee)
  • Le 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) (ie Employé -> Manager)

Dans ton cas

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

vous faites un upcasting.

Un upcast réussit toujours contrairement à un downcast qui nécessite un cast explicite car il peut potentiellement échouer à l'exécution ( InvalidCastException ).

C # propose deux opérateurs pour éviter que cette exception ne soit levée:

Partant 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.

vainqueur
la source
6

Dans le cas où vous devez vérifier chacun des objets Employee s'il s'agit d'un objet Manager, 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..
}
HOKBONG
la source
2

Réponse 1: Oui, cela s'appelait upcasting, mais la façon dont vous le faites n'est pas moderne. L'upcasting peut être effectué implicitement, vous n'avez besoin d'aucune conversion. Donc, il suffit d'écrire Employee emp = mgr; suffit pour upcasting.

Réponse 2: Si vous créez un objet de la classe Manager, nous pouvons dire que le manager est un employé. Parce que le gestionnaire de classe: l'employé décrit la relation Is-A entre la classe d'employé et la classe de gestionnaire. On peut donc dire que chaque manager est un employé.

Mais si on crée un objet de classe Employee on ne peut pas dire que cet employé est manager car classe Employee est une classe qui n'hérite d'aucune autre classe. Vous ne pouvez donc pas directement réduire cet objet de classe d'employé en objet de classe de gestionnaire.

Donc, la réponse est, si vous voulez passer d'un objet de classe d'employé à un objet de classe de gestionnaire, vous devez d'abord avoir un objet de classe de gestionnaire, puis vous pouvez le convertir à la hausse et ensuite vous pouvez le réduire.

Asad Patel
la source
-1

Upcasting et Downcasting:

Upcasting: diffusion de la classe dérivée à la classe de base Downcasting: diffusion de la classe de base à la classe dérivée

Comprenons la même chose comme exemple:

Considérez deux classes Shape comme ma classe parent et Circle comme une classe dérivée, définie comme suit:

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:

Forme s = nouvelle forme ();

Cercle c = s;

Les deux c et s font référence au même emplacement de mémoire, mais les deux ont des vues différentes, c'est-à-dire qu'en utilisant la référence "c", vous pouvez accéder à toutes les propriétés de la classe de base et de la classe dérivée, mais en utilisant la référence "s", vous pouvez accéder aux propriétés de la seule classe parente.

Un exemple pratique d'upcasting est la classe Stream qui est la classe de base de tous les types de lecteur de flux du framework .net:

Lecteur StreamReader = nouveau StreamReader (nouveau FileStreamReader ());

ici, FileStreamReader () est converti en streadm reder.

Downcasting:

Forme s = nouveau cercle (); ici comme expliqué ci-dessus, la vue de s est le seul parent, afin de le rendre à la fois pour le parent et pour un enfant, nous devons le réduire

var c = (cercle) s;

L'exemple pratique de Downcasting est la classe de bouton de WPF.

AutomatisationNerd
la source