2009-10-06 3 views
65

Je suis nouveau à C# (et OOP). Quand j'ai un code comme ce qui suit:downcast et upcast

class Employee 
{ 
    // some code 
} 


class Manager : Employee 
{ 
    //some code 
} 

Question 1: Si je autre code qui fait cela:

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

Ici Employee est un Manager, mais quand je l'ai jeté comme ça à un Employee cela signifie que je suis upcasting?

Question 2:

Quand j'ai plusieurs Employee objets de classe et quelques-uns, mais pas tous sont Manager s », comment puis-je les downcaster si possible?

+2

J'espère que cela ne vous dérange pas, j'ai corrigé les "erreurs de syntaxe" dans votre question;) – RCIX

+1

désolé je suis un peu pauvre en anglais – user184805

+1

C'est ok, pas de problème! – RCIX

Répondre

66
  1. C'est correct. Lorsque vous faites cela, vous le convertissez en objet , ce qui signifie que vous ne pouvez accéder à aucun gestionnaire spécifique. La diffusion vers le bas est l'endroit où vous prenez une classe de base, puis essayez de la transformer en une classe plus spécifique. Ceci peut être accompli avec l'aide est et un casting 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 ne sait pas que je serai heureux de corriger il!

+0

J'ai besoin d'un exemple pour savoir ce qu'est le downcasting? – user184805

+3

Évitez de redéfinir des termes bien établis: "boxing", dans le contexte de POO et C#, signifie quelque chose de plutôt différent (= enveloppant un objet de type valeur dans une référence). De plus, votre exemple pourrait (et devrait) utiliser l'opérateur 'as 'au lieu de' is', suivi d'un cast. –

+1

Je suis corrigé sur le premier point, et j'ai changé la deuxième moitié de ma réponse pour montrer les deux façons de le faire. – RCIX

40

La projection ascendante (en utilisant (Employee)someInstance) est généralement facile car le compilateur peut vous dire à la compilation si un type est dérivé d'un autre.

La rétrogradation doit cependant être effectuée au moment de l'exécution, car le compilateur ne sait pas toujours si l'instance en question est du type indiqué. 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 retourne le bon type 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 cette

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

Si vous devez vérifier chacun l'objet de l'employé si elle est un objet Manager, utiliser 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.. 
} 
3
  • 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) (c.-à-d.Manager -> Employee)
  • La diffusion descendante 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) (à savoir des employés -> Gestionnaire)

Dans votre cas

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

vous faites une coulée en source.

Un upcast réussit toujours la différence d'un baissés qui exige une distribution explicite car il peut potentiellement échouer lors de l'exécution. (InvalidCastException).

C# offre deux opérateurs pour éviter cette exception à jeter:

A partir de:

Employee e = new Employee(); 

Première:

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

Deuxième:

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

Avertissement: Quand vous faites un upcast vous ne pouvez accéder aux méthodes de la superclasse, propriétés etc ...

-1

et Downcasting transtypage ascendant:

transtypage ascendant: Coulée de dérivés de classe à base Downcasting: Casting de la classe de base à la classe dérivée

comprenons même comme un exemple:

Tenir compte deux classes forme que ma classe parente et le Cercle 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; } 
} 

transtypage ascendant:

forme s = new Shape();

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

Un exemple pratique de classe est de transtypage ascendant ruisseau qui est baseclass de tous les types de lecteur de flux du framework .NET:

lecteur StreamReader = new StreamReader (nouveau FileStreamReader());

Ici, FileStreamReader() est mis à jour vers streadm reder.

Downcasting:

forme = new Cercle(); ici comme expliqué ci-dessus, vue de s est le seul parent, afin de le rendre à la fois parent et un enfant nous avons besoin de le baisser

var c = (Cercle) s;

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

Questions connexes