Dupliqué possible: strong>
Casting: (nouveautype) vs objet comme nouveautype p>en C #, pourquoi déjà des types de référence lorsque vous pouvez utiliser "comme"? p>
casting peut générer des exceptions alors que "comme" va évitaira vers
null code> si la coulée échoue. p>
ne serait pas plus facile à utiliser avec référence types dans tous les cas? p>
par exemple: p>
xxx pré> plutôt que p>
xxx pré> blockQuote>
8 Réponses :
opérateur 'comme "fonctionne avec des types de référence uniquement. P>
La question a été mise à jour pour clarifier qu'il s'agit uniquement de types de référence uniquement (comme il parle de null code> Je pensais déjà clair déjà).
Parfois, vous voulez que l'exception soit lancée. Parfois, vous voulez essayer de convertir et NULLS est correct. Comme déjà indiqué, comme code> ne fonctionnera pas avec des types de valeur. P>
Damn, y'battez-moi à cela;) Exactement, parfois, vous voulez qu'une exception soit lancée, ce qui est parfaitement valide. +1
Pourquoi voudriez-vous que l'exception soit lancée?
Parce que le code d'appel a fait quelque chose qui n'a pas de sens et que la seule réponse sensible est de lancer une exception. Ce n'est pas différent de la façon dont si vous appeliez Charge () sur un xmldocument avec du contenu qui n'était pas XML, vous voulez que cela jette une exception. Ne pas le faire, il vous laisse simplement un objet qui ne peut pas être utilisé sensiblement, mais que vous ne savez pas ne peut pas être utilisé sensiblement.
de msdn ( comme (référence C #) ): < / p>
L'opérateur n'effectue que des conversions de référence et des conversions de boxe. L'opérateur que l'opérateur ne peut pas effectuer d'autres conversions, telles que des conversions définies par l'utilisateur, qui doivent être effectuées à la place à l'aide d'expressions moulées. P> blockQuote>
Prendre en compte tous les commentaires, nous avons rencontré cela simplement l'autre jour et que vous vous demandiez pourquoi vous feriez une distribution directe en utilisant le mot-clé Donc, si vous voulez que quelque chose échoue, utilisez une distribution directe, si vous acceptez cela ne pas échouer, utilisez le mot clé code> comme p> comme code>. Et si vous veux em> la distribution à échouer? C'est parfois l'effet souhaitable que vous souhaitez d'un casting si vous coulez d'un objet NULL. Vous appuyez ensuite sur la pile d'appel. P>
Pourquoi voudriez-vous que la volonté échoue? En outre, si la distribution échoue à l'aide de "comme", vous recevrez NULL.
Certains environnements logiciels répondent à des types génériques, comme la nôtre le fait, afin d'accroître la flexibilité. Les nouveaux types peuvent être introduits ad-hoc. Par exemple, nous utilisons des roulettes dynamiques pouvant convertir d'un type à un autre, même si elles ne sont pas liées. Ceci est fait pour que le type de fin est "convivial" (peut-être immuable ou avec des champs cachés). Si la distribution ne fonctionne pas, nous devons savoir à ce sujet!
Si, lorsque vous écrivez le code pour effectuer la distribution, vous êtes sûr que la distribution doit fonctionner, vous devez utiliser Si vous souhaitez gérer le cas où MyObject n'est pas un DataGridView, utilisez ensuite tl; dr strong> si votre code suppose quelque chose et que l'hypothèse est erronée au moment de l'exécution, le code devrait lancer une exception. P> (dataGridView) myObject code>. De cette façon, si la distribution échoue à l'avenir, votre hypothèse sur le type de MyObject provoquera une exception de moulage non valide au point où vous effectuez la distribution, au lieu d'une exception de référence NULL à un moment donné. P>
comme code> et vérifiez probablement qu'il est null avant de faire quelque chose avec elle. P>
Considérez les alternatives suivantes:
SomeClass c = (someObj as SomeClass) ?? _stockImpl;
+1 Je continue à voir foo (SomeoBJ en tant que soméclasse); code> dans le code (sans un
NULL code> chèque, c'est-à-dire). Cela me déflère pourquoi les gens font cela. Y a-t-il un livre quelque part qui dit
(soméclass) code> sont mauvais?
N'est-il pas plus facile de vérifier si la variable est NULL après la déclaration "comme", plutôt que de faire face à une exception?
Pouvez-vous faire quelque chose d'utile lorsque TOOROBJ code> est
null code>? Sinon, si votre code peut supposer que
personnobj code> est en fait
soméclass code> - alors quel est le point?
Mais si vous n'avez pas écrit foo code>, et j'ai fait? Comment savoir, lors de la réception d'un argument de programme NULL si vous vouliez dire qu'il soit nul ou pas? Peut-être que mon code est censé pouvoir accepter des arguments nuls, mais vous pensiez que vous passais un argument non nul et d'une classe d'accord. Si vous avez utilisé un casting, vous auriez dit immédiatement. Si vous avez utilisé un
comme code>, vous ne savez pas que vous ne connaissez que si vous essayez de faire quelque chose plus tard et que vous obtenez un résultat, vous n'attendez pas (ce qui pourrait même pas être une exception!)
@Tim Robinson - Si la référence est autorisée à être NULL, alors oui, vous voulez bien sûr utiliser comme code>. Dois-je mettre à jour la réponse pour clarifier cela?
Règle utile pour les nulls: traitez-les comme toxiques. Rejeter-les dans vos intrants. Évitez de les revenir en tant que sorties.
@Daniel - ce commentaire était pour @CRAIG
@Tim: les gens qui viennent de C ++ apprennent que () code> moulages sont mauvais et transférez ceci sur c # malgré la sémantique de casse très différente.
@Tim, parfois c'est raisonnable. Exemple courant est si vous avez implémenté Iequatable
objet.equals () code > est presque toujours
correspondre égale (obj comme mytype) code>, à la suite du passage de NULL et d'un type différent Devrait i> être identique dans ce cas.
@Jon Hanna - C'est un exemple de situation où la référence cible est autorisée à être null code>, comme le "contrat" de
objet.equals code> est censé le gérer par conception . Le point ici n'est pas de nier l'existence de ces situations, mais qu'ils sont comparativement rares, et il est donc généralement préférable d'arrêter
null code> s de trouver leur chemin dans les structures de données dès que possible.
Vraiment le problème sous-jacent ici est que la langue n'a aucun soutien aux références non nullables, malgré le fait que la majorité écrasante des références dans des programmes réels n'a jamais besoin de stocker la valeur null code>. QConlondon.com/london-2009/presentation/...
@Danielearwicker: Je n'ai pas vu la présentation, mais je suis curieux: comment les types de référence non nullables peuvent-ils fonctionner dans une langue qui ne forcent pas chaque champ de réseau ou de chaque champ de classe à écrire avant d'être lu? Si un algorithme sera en train de fonctionner correctement chaque élément de tableau avant que cet élément particulier soit lu, un échec de l'initialisation d'un élément provoque une null qui déclenche une exception semble moins susceptible de masquer un bogue que si tous les éléments de réseau ne nécessiteraient pas de pré-écrit avec une valeur "par défaut".
@supercat - L'idée est que la non-nullabilité serait un attribut optionnel i> d'une variable de référence, et non qu'il deviendrait obligatoire pour toutes les variables de référence. Par conséquent, un réseau ordinaire serait toujours un tableau ordinaire. Et il ne serait pas essentiel pour une langue étendue de prendre en charge des types d'éléments de tableau non nullables, voir: recherche.microsoft.com/en-us/projects/specsharp - Un tableau pourrait toujours être utilisé comme un détail de mise en œuvre interne de certains conteneurs de non-nullables.
@DanieleArwicker: Je peux voir qu'il pourrait y avoir des avantages à pouvoir déclarer qu'un emplacement de champ ou de tableau ne devrait jamais être lu quand il est null, et que si le compilateur ne peut pas confirmer de manière statique que ce ne sera pas nécessaire Générez du code pour jeter une exception si elle est [je voudrais une affectation d'un tel tableau ou d'un tel champ à une variable non nullable pour ne pas nécessiter une distribution]. Je suppose que je ne vois pas null code> comme un problème énorme, car, même si même si les erreurs liées à NULL ne sont pas marquées à la source, elles sont généralement marquées assez rapidement.
@DanieleArwicker: Je peux voir que de tels types pourraient être un avantage dans .NET, mais beaucoup plus utile seraient des variations sur "const ref". Avoir plusieurs types d'emplacement de stockage pour chaque type de classe, de sorte qu'une "liste dont les éléments encapsulent les identités des éléments de type Fnord" serait un type différent d'une "liste dont les éléments encapsulent les propriétés mutables des objets de type Fnord", par opposition Pour les deux choses étant une liste
Une raison définitive est que l'objet est, ou pourrait être (lors de la rédaction d'une méthode générique, vous ne savez peut-être pas que le code de codage) est jeté sur un type de valeur, auquel cas Une raison plus douteuse est que vous savez déjà que l'objet est du type en question. À quel point cela dépend de la façon dont vous le savez déjà. Dans le cas suivant: p> Il est difficile de justifier à l'aide d'utiliser Une autre bonne raison est que la différence entre être du mauvais type et être null se cache par Enfin, peut-être que si vous ne connaissez pas le type de l'objet, le code d'appel doit. Si le code d'appel a appelé le vôtre de manière incorrecte, ils devraient recevoir une exception. Pour permettre à la invalidationnactexception de transmettre, ou de l'attraper et de lancer une exception invalidalargument ou similaire est un moyen raisonnable et clair de le faire. P> P> comme code> ISN 't permis.
comme code> ici, comme la seule chose que cela fait vraiment, c'est ajouter un chèque redondant (peut-être Je serais optimisé, peut-être que ce ne sera pas). À l'autre extrême, si vous êtes à mi-chemin d'un état de transe avec la quantité d'informations que vous avez dans la mémoire de votre cercle, vous êtes à la mémoire de votre cerveau et sur la base de ce que vous êtes à peu près sûr que l'objet doit être de la Tapez en question, peut-être qu'il vaut mieux ajouter dans le chèque. p>
comme code>. S'il est raisonnable de passer dans une chaîne à une méthode donnée, y compris une chaîne nulle, mais il n'est pas raisonnable de passer dans un int, alors
Val sous forme de chaîne code> vient de faire une utilisation incorrecte de l'utilisation incorrecte Différente utilisation correcte, et vous venez de rendre le virus du virus à trouver et potentiellement plus dommageable. P>
mytype t = obj comme mytype; Si (t! = null) {domyTypeStuff (t); } else {domoregeneralstuff (obj); } code>
Telle est plus rapide et ne jette pas d'exceptions. Par conséquent, il est généralement préféré. Les raisons d'utiliser des mises comprennent:
Utiliser comme, vous ne pouvez attribuer que des types plus bas dans l'arborescence d'héritage à ceux qui sont plus élevés. Par exemple: p>
IEnumerable<T> GetList<T>(T item) { (from ... select) as IEnumerable<T> }
@Jarrett Meyer - Cette question demande quelle est la différence. Cette question est différente. Connaissant la différence, il demande pourquoi une fonte qui jette est meilleure qu'un casting qui ne jette pas.