Considérez le code suivant:
void Handler(object o, EventArgs e)
{
// I swear o is a string
string s = (string)o; // 1
//-OR-
string s = o as string; // 2
// -OR-
string s = o.ToString(); // 3
}
Quelle est la différence entre les trois types de casting (d'accord, le 3ème n'est pas un casting, mais vous obtenez l'intention). Lequel devrait être préféré?
string s = Convert.ToString(o)
:; 5ème:string s = $"{o}"
(ou de manière équivalente lestring.Format
formulaire pour le C # précédent)Réponses:
Lève InvalidCastException si
o
n'est pas unstring
. Sinon, assigneo
às
, même s'il l'o
estnull
.Attribue
null
às
sio
n'est pas unstring
ou sio
estnull
. Pour cette raison, vous ne pouvez pas l'utiliser avec des types de valeur (l'opérateur ne pourra jamais retournernull
dans ce cas). Sinon, attribueo
às
.Provoque une exception NullReferenceException si
o
estnull
. Attribue tout ce quio.ToString()
retournes
, quel que soit le typeo
.Utilisez 1 pour la plupart des conversions - c'est simple et direct. J'ai tendance à ne presque jamais utiliser 2 car si quelque chose n'est pas du bon type, je m'attends généralement à ce qu'une exception se produise. Je n'ai vu qu'un besoin pour ce type de fonctionnalité de retour nul avec des bibliothèques mal conçues qui utilisent des codes d'erreur (par exemple, retourner null = erreur, au lieu d'utiliser des exceptions).
3 n'est pas un transtypage et n'est qu'un appel de méthode. Utilisez-le lorsque vous avez besoin de la représentation sous forme de chaîne d'un objet non-chaîne.
la source
string s = (string)o;
À utiliser lorsque quelque chose devrait être définitivement l'autre chose.string s = o as string;
À utiliser lorsque quelque chose pourrait être l'autre chose.string s = o.ToString();
À utiliser lorsque vous ne vous souciez pas de ce que c'est mais que vous souhaitez simplement utiliser la représentation de chaîne disponible.la source
Cela dépend vraiment si vous savez si
o
c'est une chaîne et ce que vous voulez en faire. Si votre commentaire signifie qu'ilo
s'agit vraiment d'une chaîne, je préfère la(string)o
distribution directe - il est peu probable qu'elle échoue.Le plus grand avantage de l'utilisation de la distribution directe est qu'en cas d'échec, vous obtenez une InvalidCastException , qui vous indique à peu près ce qui n'a pas fonctionné.
Avec l'
as
opérateur, sio
n'est pas une chaîne,s
est défini surnull
, ce qui est pratique si vous n'êtes pas sûr et que vous souhaitez testers
:Cependant, si vous n'effectuez pas ce test, vous l'utiliserez
s
plus tard et une exception NullReferenceException sera levée. Celles-ci ont tendance à être plus courantes et beaucoup plus difficiles à retrouver une fois qu'elles se produisent dans la nature, car presque chaque ligne déréférence une variable et peut en lancer une. D'un autre côté, si vous essayez de transtyper en un type de valeur (toute primitive ou structure telle que DateTime ), vous devez utiliser le transtypage direct - leas
ne fonctionnera pas.Dans le cas particulier de la conversion en chaîne, chaque objet a un
ToString
, donc votre troisième méthode peut être correcte si elleo
n'est pas nulle et vous pensez que laToString
méthode pourrait faire ce que vous voulez.la source
as
avec des types de valeur nullable . IEo as DateTime
ne fonctionnera pas, maiso as DateTime?
...if (s is string)
place?is
ing, vous devrez de nouveau lancer de toute façon, vous aurez donc le cast puis le hard cast. Pour une raison quelconque, leas
chèque et null me semblait mieux.Si vous savez déjà dans quel type il peut être casté, utilisez un cast de style C:
Notez que ce n'est qu'avec une conversion de style C que vous pouvez effectuer une coercition de type explicite.
Si vous ne savez pas si c'est le type souhaité et que vous allez l'utiliser si c'est le cas, utilisez comme mot-clé:
Notez que as n'appellera aucun opérateur de conversion de type. Il ne sera pas non nul si l'objet n'est pas nul et nativement du type spécifié.
Utilisez ToString () pour obtenir une représentation sous forme de chaîne lisible par l'homme de tout objet, même s'il ne peut pas être converti en chaîne.
la source
Le mot clé as est bon dans asp.net lorsque vous utilisez la méthode FindControl.
Cela signifie que vous pouvez opérer sur la variable typée plutôt que de la convertir ensuite
object
comme vous le feriez avec une conversion directe:Ce n'est pas énorme, mais cela permet d'économiser des lignes de code et d'affectation de variables, en plus c'est plus lisible
la source
'as' est basé sur 'is', qui est un mot clé qui vérifie au moment de l'exécution si l'objet est compatible polimorphiquement (essentiellement si un transtypage peut être effectué) et retourne null si la vérification échoue.
Ces deux sont équivalents:
Utilisation de 'as':
Utiliser «est»:
Au contraire, la conversion de style c est également effectuée lors de l'exécution, mais lève une exception si la conversion ne peut pas être effectuée.
Juste pour ajouter un fait important:
Le mot clé 'as' ne fonctionne qu'avec les types de référence. Tu ne peux pas faire:
Dans ces cas, vous devez utiliser le casting.
la source
2 est utile pour convertir en un type dérivé.
Supposons qu'un est un animal:
obtiendra un fed avec un minimum de lancers.
la source
Selon les expériences effectuées sur cette page: http://www.dotnetguru2.org/sebastienros/index.php/2006/02/24/cast_vs_as
(cette page affiche parfois des erreurs de "référent illégal", alors actualisez-le si c'est le cas)
La conclusion est que l'opérateur "as" est normalement plus rapide qu'un cast. Parfois beaucoup plus vite, parfois à peine plus vite.
Personnellement, je pense que "as" est aussi plus lisible.
Donc, comme il est à la fois plus rapide et "plus sûr" (ne lancera pas d'exception), et peut-être plus facile à lire, je recommande d'utiliser "as" tout le temps.
la source
"(string) o" entraînera une InvalidCastException car il n'y a pas de transtypage direct.
"o as string" aura pour résultat que s sera une référence nulle, plutôt qu'une exception levée.
"o.ToString ()" n'est pas un transtypage en soi, c'est une méthode qui est implémentée par objet, et donc d'une manière ou d'une autre, par chaque classe de .net qui "fait quelque chose" avec l'instance de la classe sur laquelle il est appelé et renvoie une chaîne.
N'oubliez pas que pour la conversion en chaîne, il y a aussi Convert.ToString (someType instanceOfThatType) où someType fait partie d'un ensemble de types, essentiellement les types de base des frameworks.
la source
Toutes les réponses données sont bonnes, si je peux ajouter quelque chose: pour utiliser directement les méthodes et les propriétés de la chaîne (par exemple ToLower), vous ne pouvez pas écrire:
vous ne pouvez écrire que:
mais vous pourriez écrire à la place:
L'
as
option est plus lisible (du moins à mon avis).la source
(o as string).ToLower()
place des multiples crochets déroutants.Est préférable, car il évite la pénalité de performance de la double coulée.
la source
Il semble que les deux soient conceptuellement différents.
Casting direct
Les types n'ont pas à être strictement liés. Il se décline dans tous les types de saveurs.
C'est comme si l'objet allait être converti en quelque chose d'autre.
Opérateur AS
Les types ont une relation directe. Un péché:
On a l'impression que vous allez manipuler l'objet d'une manière différente.
Échantillons et IL
la source
Je voudrais attirer l'attention sur les spécificités suivantes de l' opérateur as :
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/as
la source
Lorsque j'essaie d'obtenir la représentation sous forme de chaîne de tout (de tout type) qui pourrait potentiellement être nul, je préfère la ligne de code ci-dessous. Il est compact, il appelle ToString () et il gère correctement les valeurs nulles. Si o est nul, s contiendra String.Empty.
la source
Puisque personne ne l'a mentionné, le plus proche de instanceOf to Java par mot-clé est le suivant:
la source
Utilisez la conversion directe
string s = (string) o;
si dans le contexte logique de votre applicationstring
est le seul type valide. Avec cette approche, vous obtiendrezInvalidCastException
et implémenterez le principe de Fail-fast . Votre logique sera protégée contre la transmission du type non valide ou obtiendra NullReferenceException si l'as
opérateur est utilisé .Si la logique attend plusieurs types différents castés
string s = o as string;
et cochez-lanull
ou utilisez l'is
opérateur.De nouvelles fonctionnalités intéressantes sont apparues dans C # 7.0 pour simplifier la distribution et la vérification est une correspondance de modèle :
la source
Les deux formes suivantes de conversion de type (conversion) sont prises en charge en C #:
|
(CV
• Convertir le type statique de v en c dans l'expression donnée
• Possible uniquement si le type dynamique de v est c ou un sous-type de c
• Sinon, une InvalidCastException est levée
|
v comme C
• Variante non mortelle de (c) v
• Ainsi, convertissez le type statique de v en c dans l'expression donnée
• Renvoie null si le type dynamique de v n'est pas c, ou un sous-type de c
la source