2010-01-12 6 views

Respuesta

10

Estos no son todos ejemplos de fundición.

Este es un reparto:

string someVariable = (string) someOtherVariable; 

Ésta es llamada al método:

string someVariable = someOtherVariable.ToString(); 

Y esto es un reparto segura:

string someVariable = someOtherVariable as string; 

El primer y tercer ejemplos son moldes reales . El primer elenco tiene el potencial de arrojar un InvalidCastException, mientras que el tercer ejemplo no lanzará esa excepción. Es por eso que el operador as se conoce como un yeso seguro.

+0

Si no puedo lanzar alguna OtraVariable en una cadena, ¿qué hará un lanzamiento seguro? – Deane

+3

@Deane: En su lugar devolverá nulo. – rmac

+1

Vale la pena mencionar que el método 'ToString' básicamente le pide a someOtherVariable que se represente a sí mismo como una cadena y la implementación predeterminada (heredada de Object) simplemente devuelve el nombre de la clase. En cuanto al "yeso seguro", "como" intenta empacar el valor de alguna OtraVariable en una caja en forma de cadena, y simplemente deja la caja vacía si no encaja (es decir, algunaVariable será nula si alguna OtraVariable no se puede convertir a cuerda). – Rory

0

Esto es 100% preferencia personal aquí, pero para mí utilizo el folowing:

string someVariable = (string) someOtherVariable; 

Al convertir a un tipo de niño o de los padres (por ejemplo NetworkStream-> Stream.)

string someVariable = someOtherVariable.ToString(); 

Al convertir a un nuevo tipo (int -> cadena)

Y nunca uso este último método (como cadena), principalmente porque provengo de un fondo C/C++ prefiero el() y es un poco más conciso.

+0

La conversión a un tipo de matriz es implícita por lo que rara vez se había tiene que realizar un lanzamiento explícito en ese caso. Además, creo que "como" a veces es útil cuando se está buscando un tipo particular y instancias nulas al mismo tiempo (ya que "como" devuelve nulo si el objeto no es del tipo especificado). Ex. Es posible que tenga un método que tome un parámetro opcional "remitente" de tipo objeto (para satisfacer un requisito de interfaz), pero todavía le preocupa su tipo: Foo x = remitente como Foo; if (x! = null) x.Bar(); –

2

La palabra clave as es muy útil si cree que la conversión fallará durante una actualización. Por ejemplo, si quiero realizar la misma operación en tipos similares en una lista de control ... digamos desactivando todas las casillas de verificación:

foreach (Control ctrl in Controls) 
{ 
    Checkbox box = ctrl as Checkbox; 
    if (box != null) 
     box.Checked = false; 
} 

De esta manera, si mi lista tiene otra cosa, como un cuadro de texto o una label, no se lanza ninguna excepción (simplemente configura la variable = null si falla) y es muy eficiente. No hay una sobrecarga de excepción.

+0

También es más rápido que un control de tipo y luego lanzar. –

0

Hay una gran diferencia entre el casting con paréntesis y el casting con "as".

Básicamente, el paréntesis lanzará una excepción mientras que "as" devolverá nulo en lugar de generar una excepción.

información más detallada here

0
string someVariable = (string) someOtherVariable; 

esta es su buen casting normales de edad y va a lanzar una excepción si se intenta convertir algo en algo que no se puede lanzar (por lo tanto, algunas veces usted necesita para comprobar si son moldeable)

string someVariable = someOtherVariable.ToString(); 

no es realmente la fundición, la ejecución de un método que puede provenir de diferentes lugares (interfaces), sino que todos los objetos en C# tienen, ya que heredan del objeto Object, que lo tiene.Tiene una operación predeterminada que le da el nombre del tipo del objeto, pero puede sobrecargarlo para imprimir lo que quiera que su clase imprima en el método ToString.

string someVariable = someOtherVariable as string; 

Ésta es una nueva C# casting, se comprobará en primer lugar si es moldeable mediante el uso de un variable is string primero y luego hacer la colada si es válido o devolver un valor nulo si no es así, por lo que podría ser un silencio error si espera excepciones, ya que debe verificar contra nulo.

Básicamente

myType as myOtherType 

es lo mismo que:

var something = null; 
if(myType is myOtherType) 
{ 
    something = (myType) myotherType; 
} 

excepto que como será comprobar y fundido en un solo paso, y no en 2.

2

Las ideas de CAST y CONVERT no debe confundirse aquí. Casting implica ver un objeto como si fuera de otro tipo. Convertir implica transformar un objeto a otro tipo.

Si su intención es CASTAR a una cadena, debe usar la primera o tercera. (La opción depende de lo que quiera que suceda en la condición de error. Consulte la respuesta de bangoker.)

Si su intención es CONVERTIR a una cadena, debe usar la segunda. (O mejor, la instrucción modificada de ChaosPandion con el operador trinario.) Esto se debe a que el comportamiento del método ToString se define como la conversión del objeto en una representación de cadena.

5

Las tres hacen cosas diferentes, ninguna es "más correcta", depende de su situación. Si tiene un grupo de objetos que pueden no ser cadenas, probablemente use .ToString() (con una comprobación nula, si espera valores nulos).

Si solo le importan las cadenas no nulas, pero todavía espera recibir cadenas, utilice un molde "como" y luego ignore los valores que entran como nulos (o bien fueron originalmente nulos, o bien de un tipo no de cadena)

si espera recibir solo cadenas, lo mejor es usar el molde (de cadena). Esto expresa la intención mejor en el código.

object foo = 5; 
string str = (string)foo; // exception 
string str = foo as string; // null 
string str = foo.ToString(); // "5" 

object foo = "bar"; 
string str = (string)foo; // "bar" 
string str = foo as string; // "bar" 
string str = foo.ToString(); // "bar" 

object foo = null; 
string str = (string)foo; // null 
string str = foo as string; // null 
string str = foo.ToString(); // exception 
0

En primer lugar, usted debe avoid casting with AS operator. El artículo vinculado explica por qué.

En segundo lugar, puede usar el operador AS SOLO si espera que el valor no sea del tipo que usted emite también. Por lo tanto, deberá verificarlo manualmente.

También la llamada obj.ToString() método no es una pieza de fundición, es convierte objeto a una representación de cadena (que en el caso de una cadena en sí es la misma cadena). Esto puede ser superado por cualquier clase.


Por lo tanto, como regla general que siguen esta:

  1. Use siempre (Type) fundición.
  2. Utilice el operador as solo si el objeto puede ser de otro tipo que no sea el que usted haya creado.
  3. Si usa el operador as - SIEMPRE verifique el resultado para NULO.
  4. Use ToString solo en los casos en que necesite mostrar información sobre el objeto.
+1

Usar su propio blog como punto de referencia en una opinión no es la mejor defensa. "como" y un cheque nulo es más rápido que un control de tipo y luego lanzar. –

+0

No estoy argumentando que AS es más rápido. Estoy diciendo que siempre se debe realizar una verificación As + Null. Cuando en realidad muchos desarrolladores simplemente olvidan verificar nulos. Por esa razón hay una buena práctica en su lugar: use casting explícito (corchetes) que realizará una verificación de tipo y lanzará un error descriptivo si el fundido de tipo ha fallado. –

6

Aquí está mi artículo sobre el tema.

http://blogs.msdn.com/ericlippert/archive/2009/10/08/what-s-the-difference-between-as-and-cast-operators.aspx

En cuanto a cuál es el "más correcta", la que es más correcto es el que tiene el significado que tiene la intención de transmitir al lector del programa.

"ToString()" transmite "probablemente no sea una cadena; si no lo es, entonces deseo obtener del objeto una cadena que lo represente".

El operador de "transmitir" transmite "esto es una cadena, y estoy dispuesto a bloquear mi programa si estoy equivocado", o al revés, "esto no es una cadena y quiero llamar a un usuario- conversión definida en este objeto a la cadena ".

El operador "as" transmite "esto podría ser una cadena y si no es así, quiero que el resultado sea nulo".

¿A cuál de esas cuatro cosas quiere decir?

0

Si su pregunta sobre la mejor práctica para la sintaxis de moldear una variable, entonces yo prefiero usar siguiente:

var someVariable = someOtherVariable as string ?? string.Empty; 

Off supuesto se puede utilizar en lugar de someVariableDefaultValue String.Empty.

En caso de que si no lanzas de cadena, pero en el complejo de algún tipo, entonces te recomiendo siguiente sintaxis, algunas veces llamada la seguridad de navegación del operador:

var complexVariable = otherComplexVariable as ComplexType; 
if (complexVariable?.IsCondition) 
{ 
    //your code if cast passed and IsCondition is true 
} 
else 
{ 
    //your code if cast not passed or IsCondition is false 
} 
Cuestiones relacionadas