2010-04-01 2 views
4

MyClassName je me demandais quelle est la meilleure méthode pour les objets de coulée pour C#:(MyClassName) objet par rapport à l'objet comme

MyClassName test = (MyClassName)object; 

MyClassName test = object as MyClassName; 

Je sais déjà que si vous faites la première façon, vous obtenez une exception, et la seconde façon de définir le test comme nul. Cependant, je me demandais pourquoi faire l'un sur l'autre? Je vois la première façon beaucoup, mais j'aime la deuxième façon parce que je peux vérifier la nullité ...

S'il n'y a pas une «meilleure façon» de le faire, quelles sont les lignes directrices pour l'utilisation d'un sens ou l'autre?

Répondre

8

Pas de ligne directrice officielle, mais voici comment je le ferais.

Si vous souhaitez réellement , l'exception (c'est-à-dire vous pensez que l'objet ne peut jamais être d'un type différent de MyClassName), utilisez la distribution explicite. Exemple (WinForms):

private void checkbox_CheckedChanged(object sender, EventArgs e) { 
    // We've hooked up this event only to CheckBox controls, so: 
    CheckBox checkbox = (CheckBox)sender; 
    // ... 
} 

Si vous voulez gérer les types qui ne sont pas MyClassName gracieusement, utilisez le mot-clé as.

0

Eh bien, il y a une raison simple d'utiliser le mot-clé as (sur la coulée à l'aide de crochets): Ce est parce que l'opérateur ne as jeter une exception quand il échoue, mais remplit la place la variable avec null . Vérifie si la valeur était nulle vérifiée si le code a fonctionné ou non.

Notez que dans le monde réel que vous voulez la gestion des exceptions dans le bloc entier , Incase l'utilisateur sélectionne le mauvais type de dll, ou son accès est refusé , ou ... eh bien, vous obtenez le image. Cela signifie que vous pouvez librement utiliser des crochets pour le lancer - mais c'est à mon avis une méthode plus élégante de faire quelque chose où vous voulez savoir si elle a réussi ou échoué.

source: http://www.nullify.net/Article/181.aspx

0

En utilisant le mot-clé as est plus sûr comme vous le dites, et est la chose à utiliser si vous n'êtes pas 100% sûr du type de l'objet que vous essayez de lancer. Inversement, utilisez la méthode (cast) si vous souhaitez une exception si la distribution échoue. Cependant, si vous utilisez également is, alors as devient redondant. Par exemple, le code suivant est assez fréquent:

MyClass mc; 

if (someObject is MyClass) 
{ 
    mc = (MyClass)someObject; 
} 
+1

Je utiliserais comme dans cette situation car il en résulte une seule vérification de type par opposition à deux. –

+0

Notez que le code réellement généré pour 'if (someObject is MyClass)' est en fait 'if ((someObject as MyClass)! = Null)' –

+0

N'utilisez pas ** both ** 'is' et le' (cast) 'syntaxe, vous encourez deux fois le coût de la vérification de type. Si vous avez déjà déterminé le type en utilisant 'is', il est parfaitement sûr de faire le cast en utilisant' as', et beaucoup plus rapidement car il peut contourner toutes les vérifications de conversion implicites. –

0

Si vous savez que l'objet est MyClassName, puis utilisez la première méthode (coulée directe). Si vous n'êtes pas sûr, puis utilisez la deuxième méthode et vérifier nul ou vérifier le type en utilisant is avant la coulée directe:

if (obj is MyClassName) 
{ 
    MyClassName test = (MyClassName)obj; 
} 
+0

N'utilisez pas ** both ** 'is' et la syntaxe' (cast) ', vous encourez deux fois le coût de la vérification de type. Si vous avez déjà déterminé le type en utilisant 'is', il est parfaitement sûr de faire le cast en utilisant' as', et beaucoup plus rapidement car il peut contourner toutes les vérifications de conversion implicites. –

+1

Vous avez raison: http://stackoverflow.com/questions/496096/casting-vs-using-the-as-keyword-in-the-clr. Le seul problème que j'ai avec 'as 'est que c'est une erreur d'exécution si la distribution échoue et vous avez oublié de vérifier null. Tester avec 'is' avant la distribution empêche cela. Et je doute qu'il y ait une réelle différence de performance à moins de faire des millions de lancers en boucle. –

1

Notez que as ne fonctionne que pour les types de référence. Si vous devez décocher un type de valeur, vous devez utiliser la distribution de type C.

0

Vérifiez cet article sur Prefix-casting vs As-Casting

L'auteur appelé casting préfixe "Avec fiable," et comme coulée "Incantation rapide."

Il a plusieurs bons exemples de quand utiliser chacun, et les raisons pour lesquelles rapide n'est pas toujours mieux. J'espère que cela t'aides!

+1

Il peut être utile de souligner que les tests de référence auxquels cet article fait référence ont été effectués en 2004 sur la version 1 du framework .NET et sur C# 2.0. L'examen des commentaires suggère que les différences sont devenues beaucoup plus floues dans les nouvelles versions du framework et du compilateur C#. Même en passant par les benchmarks originaux, les différences entre les deux méthodes sont très faibles pour 1 million de lancers! Cela semble être un cas clair d'écrire ce qui est le plus clair, ne vous embêtez pas avec des micro-optimisations inutiles. –

+0

Bon point Graham. Je suis tombé sur un article depuis ce post qui dit que le casting explicite est compilé maintenant pour être effectivement un cast avec une vérification nulle. Merci pour vos commentaires. Je suppose que la seule différence est de savoir si vous obtenez une valeur nulle ou une exception nulle ... – Audie

Questions connexes