C'est probablement trivial, mais je ne peux pas penser à une meilleure façon de le faire. J'ai un objet COM qui renvoie une variante qui devient un objet en C #. La seule façon que je peux obtenir cela dans un int est
int test = int.Parse(string.Format("{0}", myobject))
Y a-t-il une manière plus propre de faire ceci? Merci
Vous avez plusieurs options:
(int)
- Opérateur de distribution. Fonctionne si l’objet est déjà un entier situé à un certain niveau dans la hiérarchie de l’héritage ou s’il existe une conversion implicite.
int.Parse()/int.TryParse()
- Pour convertir une chaîne de format inconnu.
int.ParseExact()/int.TryParseExact()
- Pour convertir une chaîne dans un format spécifique
Convert.ToInt32()
- Pour convertir un objet de type inconnu. Il utilisera une conversion explicite et implicite ou une implémentation IConvertible, le cas échéant.
as int?
- Notez le "?". L'opérateur as
ne concerne que les types de référence et j'ai donc utilisé "?" pour signifier un Nullable<int>
. L'opérateur "as
" fonctionne comme Convert.To____()
, mais pensez à TryParse()
plutôt qu'à Parse()
: il retourne null
plutôt que de déclencher une exception si la conversion échoue.
Parmi ceux-ci, je préférerais (int)
si l'objet n'est en réalité qu'un entier en boîte. Sinon, utilisez Convert.ToInt32()
dans ce cas.
Notez qu’il s’agit d’une très réponse générale : je voudrais attirer votre attention sur la réponse de Darren Clark, car j'estime que le problème est bien résolu spécifique ici, mais est arrivé en retard et n'a pas encore été voté. Il obtient mon vote pour "réponse acceptée", de toute façon, pour également recommander (int), pour indiquer que si cela échoue, (int)(short)
pourrait fonctionner à la place, et pour vous recommander de vérifier votre débogueur pour connaître le type d'exécution réel.
La distribution (int) myobject devrait fonctionner correctement.
Si cela vous donne une exception de distribution non valide, c'est probablement parce que le type de variante n'est pas VT_I4. Mon pari est qu’une variante avec VT_I4 est convertie en un entier en boîte, VT_I2 en un court en boîte, etc.
Lors du transtypage sur un type de valeur encadré, il est uniquement valide de le transtyper vers le type encadré. Par exemple, si la variante renvoyée est en fait un VT_I2, alors (int) (short) myObject devrait fonctionner.
Le moyen le plus simple de savoir est d'inspecter l'objet renvoyé et de voir son type dans le débogueur. Assurez-vous également que, dans l'assembly d'interopérabilité, la valeur de retour est marquée avec MarshalAs (UnmanagedType.Struct)
Convert.ToInt(myobject);
Ceci gérera le cas où myobject
est null
et renvoie 0
, au lieu de lancer une exception.
Utilisez Int32.TryParse
comme suit.
int test;
bool result = Int32.TryParse(value, out test);
if (result)
{
Console.WriteLine("Sucess");
}
else
{
if (value == null) value = "";
Console.WriteLine("Failure");
}
J'énumère la différence dans chacune des manières de lancer. Quel type particulier de casting gère et ne le fait pas?
// object to int
// does not handle null
// does not handle NAN ("102art54")
// convert value to integar
int intObj = (int)obj;
// handles only null or number
int? nullableIntObj = (int?)obj; // null
Nullable<int> nullableIntObj1 = (Nullable<int>)obj; // null
// best way for casting from object to nullable int
// handles null
// handles other datatypes gives null("sadfsdf") // result null
int? nullableIntObj2 = obj as int?;
// string to int
// does not handle null( throws exception)
// does not string NAN ("102art54") (throws exception)
// converts string to int ("26236")
// accepts string value
int iVal3 = int.Parse("10120"); // throws exception value cannot be null;
// handles null converts null to 0
// does not handle NAN ("102art54") (throws exception)
// converts obj to int ("26236")
int val4 = Convert.ToInt32("10120");
// handle null converts null to 0
// handle NAN ("101art54") converts null to 0
// convert string to int ("26236")
int number;
bool result = int.TryParse(value, out number);
if (result)
{
// converted value
}
else
{
// number o/p = 0
}
var intTried = Convert.ChangeType(myObject, typeof(int)) as int?;
Il y a aussi TryParse .
De MSDN:
private static void TryToParse(string value)
{
int number;
bool result = Int32.TryParse(value, out number);
if (result)
{
Console.WriteLine("Converted '{0}' to {1}.", value, number);
}
else
{
if (value == null) value = "";
Console.WriteLine("Attempted conversion of '{0}' failed.", value);
}
}
Étrange, mais la réponse acceptée semble erronée à propos de la distribution et de Convert, ce qui veut dire que mes tests et la lecture de la documentation ne doivent pas non plus prendre en compte les opérateurs implicites ou explicites.
Donc, si j'ai une variable de type objet et que la classe "boxed" a des opérateurs implicites définis, ils ne fonctionneront pas.
Au lieu de cela, un autre moyen simple, mais le coût de la performance est de lancer avant dans dynamique.
(int) (dynamique) monObjet.
Vous pouvez l'essayer dans la fenêtre interactive de VS.
public class Test
{
public static implicit operator int(Test v)
{
return 12;
}
}
(int)(object)new Test() //this will fail
Convert.ToInt32((object)new Test()) //this will fail
(int)(dynamic)(object)new Test() //this will pass
Peut-être que Convert.ToInt32 .
Attention aux exceptions, dans les deux cas.