2009-04-13 13 views
122

Esto es probablemente trivial, pero no puedo pensar en una mejor manera de hacerlo. Tengo un objeto COM que devuelve una variante que se convierte en un objeto en C#. La única forma en que puedo obtener esto en un int esMejor forma de lanzar objetos a int

int test = int.Parse(string.Format("{0}", myobject)) 

¿Hay alguna manera más clara de hacerlo? Gracias

Respuesta

266

tiene varias opciones: operador

  • (int) — moldeada. Funciona si el objeto ya es entero en algún nivel en la jerarquía de herencia o si hay una conversión implícita definida.

  • int.Parse()/int.TryParse() — Para convertir desde una cadena de formato desconocido.

  • int.ParseExact()/int.TryParseExact() — Para la conversión de una cadena en un formato específico

  • Convert.ToInt32() — Para convertir un objeto de tipo desconocido. Utilizará una conversión explícita e implícita o una implementación IConvertible si se define alguna.

  • as int? — ¿Nota "?". El operador as es solo para tipos de referencia, y entonces usé "?" para significar un Nullable<int>. El operador "as" funciona como Convert.To____(), pero piensa TryParse() en lugar de Parse(): devuelve null en lugar de arrojar una excepción si la conversión falla.

De estos, yo preferiría (int) si el objeto es en realidad un número entero en caja. De lo contrario, use Convert.ToInt32() en este caso.

Tenga en cuenta que este es un muy generales respuesta: Quiero tirar un poco de atención a la respuesta de Darren Clarke, porque creo que hace un buen trabajo frente a los detalles aquí, pero llegué tarde y no fue votado como bien todavíaObtiene mi voto para "respuesta aceptada", de todos modos, para también recomendar (int), para señalar que, si falla, podría funcionar (int)(short) y, para recomendarlo, verifique su depurador para averiguar el tipo de tiempo de ejecución real.

+0

Encontré un punto que no era realmente un error, pero tal vez simplificaba demasiado las cosas para que alguien pudiera pensar eso. Eliminé esa oración y agregué un enlace a la documentación autorizada. –

+0

¿Funcionará el reparto directo con una conversión implícita? Tenía la impresión de que eso solo haría unboxing estrictamente, no otras conversiones. –

+0

No es exactamente una respuesta, pero lea esto: http://blogs.msdn.com/ericlippert/archive/2009/03/19/representation-and-identity.aspx –

8

Utilice Int32.TryParse de la siguiente manera.

int test; 
    bool result = Int32.TryParse(value, out test); 
    if (result) 
    { 
    Console.WriteLine("Sucess");   
    } 
    else 
    { 
    if (value == null) value = ""; 
    Console.WriteLine("Failure"); 
    } 
+0

En realidad, Parse llama a TryParse y arroja una excepción si TryParse devuelve falso. Entonces TryParse no maneja la excepción porque nunca lanza una. – Samuel

+0

Bien, técnicamente, ambos llaman al mismo método NumberToInt32, pero solo Parse arroja excepciones cuando no funciona. – Samuel

+0

TryParse aún requiere convertir la variante en una cadena. AFAIK, el problema no es convertir de una cadena a una int, sino de una variante que es una int a una int real. –

17
Convert.ToInt(myobject); 

Esto manejar el caso en que es myobjectnull y volver 0, en lugar de lanzar una excepción.

2

También hay 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); 
     } 
    } 
28

El molde (int) myobjectdebería solo trabajo.

Si eso le da una excepción de conversión no válida, entonces es probablemente porque el tipo de variante no es VT_I4. Mi apuesta es que una variante con VT_I4 se convierte en un int en caja, VT_I2 en un corto en caja, etc.

Al hacer un molde en un tipo de valor encuadrado solo es válido para convertirlo al tipo encuadrado. Por ejemplo, si la variante devuelta es realmente un VT_I2, entonces (int) (corto) myObject debería funcionar.

La manera más fácil de averiguarlo es inspeccionando el objeto devuelto y echando un vistazo a su tipo en el depurador. También asegúrese de que en el ensamblado de interoperabilidad que tiene el valor de retorno marcado con MarshalAs (UnmanagedType.Struct)

2
var intTried = Convert.ChangeType(myObject, typeof(int)) as int?; 
+1

Encontré esta respuesta realmente útil, estaba buscando convertir un byte en un int, y lo hice funcionar usando 'Convert.ChangeType'. Yo diría que podría no ser la respuesta perfecta para OP, pero definitivamente es útil para algunos. –

2

estoy enumerando la diferencia en cada una de las formas de fundición. ¿Qué tipo particular de casting maneja y no?

// 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 
    } 
Cuestiones relacionadas