169 votes

C# « comme » fonte classique de cast vs

Double Possible:
Casting vs à l'aide de l' " comme mot-clé dans la CLR

J'ai récemment appris une autre façon de fonte. Plutôt que d'utiliser

SomeClass someObject = (SomeClass) obj;

on peut utiliser cette syntaxe:

SomeClass someObject = obj as SomeClass;

qui semble renvoyer la valeur null si obj n'est pas un SomeClass, plutôt que de lancer une classe fonte d'exception.

Je vois que cela peut conduire à une exception NullReferenceException si le casting a échoué et j'essaie d'accéder à la someObject variable. Alors je me demandais quelle est la justification de cette méthode? Pourquoi devrait-on utiliser ce moyen de la fonte plutôt que de la (vieille) il semble que déplacer le problème de l'échec d'une fonte "plus en profondeur" dans le code.

218voto

Brian Ball Points 6468

Avec le "classique" de la méthode, si la conversion échoue, une exception est levée. Avec la méthode, il en résulte la valeur null, ce qui peut être vérifié, et d'éviter une exception levée.

Aussi, vous pouvez seulement utiliser "que" avec les types de référence, donc si vous êtes typecasting à un type de valeur, vous devez toujours utiliser le "classique" de la méthode.

Edit:

Depuis cette réponse est en train de devenir populaire, j'ai pensé que je voudrais corriger le paragraphe précédent (merci à ceux qui ont commenté et a souligné pour moi). L' as méthode ne peut être utilisée pour les types qui peuvent être affectés à une null de la valeur. Que l'utilisation de seulement les types de référence, mais quand .NET 2.0 est sorti, il introduit la notion de nullable type de valeur. Étant donné que ces types de peut être affecté à une null de la valeur, ils sont valables pour une utilisation avec l' as de l'opérateur.

46voto

Matěj Zábský Points 9179

La comparaison nulle est beaucoup plus rapide que la levée et l’interception des exceptions. Exceptions ont une surcharge significative - trace de la pile doit être assemblée etc.

Exceptions devraient représenter un état inattendu, qui souvent ne représente pas la situation (qui est à ce moment `` fonctionne mieux).

31voto

Zooba Points 6440

Dans certains cas, il est facile de traiter avec un null qu'une exception. En particulier, la coalescence de l'opérateur est à portée de main:

SomeClass someObject = (obj as SomeClass) ?? new SomeClass();

Il simplifie également le code là où vous êtes (à ne pas utiliser le polymorphisme, et) de branchement en fonction du type d'un objet:

ClassA a;
ClassB b;
if ((a = obj as ClassA) != null)
{
    // use a
}
else if ((b = obj as ClassB) != null)
{
    // use b
}

Comme précisé sur la page MSDN, l' as opérateur est équivalent à:

expression is type ? (type)expression : (type)null

ce qui évite l'exception totalement en faveur d'une plus vite type de test, mais aussi les limites de son utilisation à des types qui prennent en charge null (types de référence et d' Nullable<T>).

7voto

JaredPar Points 333733

L' as opérateur est utile dans plusieurs circonstances.

  1. Quand vous avez seulement besoin de savoir qu'un objet est d'un type spécifique, mais n'ont pas besoin spécifiquement de la loi sur les membres de ce type
  2. Si vous souhaitez éviter les exceptions et à la place explicitement traitent null
  3. Vous voulez savoir si il y a un CLR conversion entre les objets et non pas seulement de certains défini par l'utilisateur de conversion.

Le 3ème point est subtile mais importante. Il n'y a pas un mappage 1-1 entre ce qui jette un va réussir avec l'opérateur de cast et ceux qui vont réussir avec l' as de l'opérateur. L' as opérateur est strictement limitée à la CLR conversions et ne considérera pas les conversions définies par l'utilisateur (l'opérateur de cast).

Plus précisément l' as opérateur permet uniquement pour les suivants (à partir de la section 7.9.11 du C# lang spec)

  • Une identité (§6.1.1), référence implicite (§6.1.6), la boxe (§6.1.7), référence explicite (§6.2.4), ou unboxing (§6.2.5) conversion existe à partir du type de E T.
  • Le type de E ou T est un type ouvert.
  • E est le littéral null.

3voto

Adam Robinson Points 88472

L' as mot-clé est utile lorsque vous avez réellement ne savez pas quel type de la variable peut être. Si vous avez une seule fonction qui va suivre différents chemins de code selon la catégorie de paramètre, alors vous avez deux choix:

Tout d'abord, à l'aide d'un normal en fonte:

if(myObj is string)
{
    string value = (string)myObj;

    ... do something
}
else if(myObj is MyClass)
{
    MyClass = (MyClass)myObj;
}

Cela exige que vous vérifiez le type de l'objet à l'aide d' is , de sorte que vous n'essayez pas de le convertir en quelque chose qui va à l'échec. C'est aussi un peu redondant, comme l' is-type de la vérification se fait à nouveau dans le casting (de sorte qu'il peut lancer une exception si nécessaire).

L'alternative est d'utiliser as.

string myString = myObj as string;
MyClass myClass = myObj as MyClass;

if(myString != null)
{

}
else if(myClass != null)
{

}

Cela rend le code un peu plus courte et élimine également le redondante vérification de type.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X