350 votes

Est-il sensé d'utiliser "as" au lieu d'un cast même s'il n'y a pas de vérification nulle?

Dans le développement des blogs, en ligne, des exemples de code et (récemment) même d'un livre, je garde en trébuchant sur un code comme ceci:

var y = x as T;
y.SomeMethod();

ou, encore pire:

(x as T).SomeMethod();

Qui n'a pas de sens pour moi. Si vous êtes sûr qu' x est de type T, vous devez utiliser directement exprimés: (T)x. Si vous n'êtes pas sûr, vous pouvez utiliser as mais besoin de vérifier pour null avant d'effectuer quelque opération. Tout ce que le code ci-dessus n'est à son tour un (utile) InvalidCastException dans un (inutile) NullReferenceException.

Suis-je le seul qui pense que ce un abus flagrant de l' as mot-clé? Ou ai-je raté quelque chose d'évident et le schéma ci-dessus fait réellement sens?

252voto

Mehrdad Afshari Points 204872

Votre compréhension est vrai. Qui sonne comme essayer de micro-optimiser pour moi. Vous devez utiliser une normale de voter lorsque vous êtes sûr du type. En plus de générer un plus raisonnable d'exception, c'est aussi ne pas jeûner. Si vous vous trompez au sujet de votre hypothèse sur le type, votre programme ne fonctionnera pas immédiatement et vous serez en mesure de voir la cause de la panne immédiatement plutôt que d'attendre une NullReferenceException ou ArgumentNullException ou même une erreur de logique dans l'avenir. En général, un as expression qui n'est pas suivie par un null case quelque part est une odeur de code.

D'autre part, si vous n'êtes pas sûr au sujet de la fonte et de l'attendre à l'échec, vous devez utiliser as , au lieu de la normale coulé enveloppé avec un try-catch bloc. En outre, l'utilisation de l' as est recommandé au cours d'une vérification de type suivi par un casting. Au lieu de:

if (x is SomeType)
   ((SomeType)x).SomeMethod();

ce qui génère un isinst instructions pour l' is mot-clé, et un castclass instructions pour le casting (acquittent efficacement de la fonte à deux reprises), vous devez utiliser:

var v = x as SomeType;
if (v != null)
    v.SomeMethod();

Cela ne génère un isinst enseignement. La première méthode a une potentielle faille de sécurité dans des applications multithread comme une condition de concurrence peut causer de la variable à modifier son type après l' is vérifier réussi et ne parviennent pas à la fonte de la ligne. Cette dernière méthode n'est pas sujette à l'erreur.


La solution suivante est pas recommandé pour une utilisation dans le code de production. Si vous avez vraiment la haine fondamentale à construire en C#, vous pourriez envisager de passer à VB ou une autre langue.

Dans le cas où un désespérément déteste le casting de la syntaxe, il/elle peut écrire une méthode d'extension pour imiter le casting:

public static T To<T>(this object o) { // Name it as you like: As, Cast, To, ...
    return (T)o;
}

et l'utilisation d'un pur[?] syntaxe:

obj.To<SomeType>().SomeMethod()

42voto

Rubens Farias Points 33357

À mon humble avis, as juste un sens lorsqu'il est combiné avec un contrôle de null :

 var y = x as T;
if (y != null)
    y.SomeMethod();
 

39voto

Larry Fix Points 443

L'utilisation de 'as' n'applique pas les conversions définies par l'utilisateur alors que la distribution les utilisera le cas échéant. Cela peut être une différence importante dans certains cas.

36voto

Eric Lippert Points 300275

J'ai écrit un peu à ce sujet ici:

http://blogs.msdn.com/ericlippert/archive/2009/10/08/what-s-the-difference-between-as-and-cast-operators.aspx

Je comprends votre point de vue. Et je suis d'accord avec l'essentiel: un opérateur de cast communique "je suis sûr que cet objet peut être converti à ce type, et je suis prêt à prendre le risque d'une exception si je me trompe", tandis qu'un "comme" opérateur communique "je ne suis pas sûr que cet objet peut être converti de ce type; donnez-moi une valeur null si je me trompe".

Cependant, il y a une différence subtile. (x, T).Quelle que soit la (les) communique "je ne sais juste que x peut être converti en T, mais en plus, que cela n'implique que la référence ou unboxing conversions, et, en outre, que x n'est pas nulle". Qui ne communiquer une information différente de celle ((T)x).Quelle que soit la(), et peut-être que c'est ce que l'auteur du code de l'intention.

16voto

Joe Points 60749

J'ai souvent vu des références à cette trompeuse de l'article comme une preuve que le "comme" est plus rapide que la coulée.

Les plus évidentes trompeuse aspects de cet article est le graphique, ce qui n'indique pas ce qui est mesuré: je soupçonne que c'est la mesure échec de jette (où le "comme" est évidemment beaucoup plus rapide qu'aucune exception n'est levée).

Si vous prenez le temps de faire les mesures, alors vous verrez que le casting est, comme vous vous y attendez, plus rapide que "comme" quand le plâtre réussit.

Je crois que cela peut être une raison pour le "culte du cargo" l'utilisation du mot-clé au lieu d'un plâtre.

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