Pregunta

I define el siguiente struct:

public struct Call
{
    public SourceFile caller;
    public SourceFile callee;

    public Call(SourceFile caller, SourceFile callee)
    {
        this.caller = caller;
        this.callee = callee;
    }
}

Más tarde, asignarlo a la propiedad Tag de otro objeto:

line.Tag = new Call(sf1, sf2);

Pero cuando intento para recuperar la propiedad Tag como tal,

Call call = line.Tag as Call;

Visual Studio da el siguiente error de compilación:

  

El operador como debe ser utilizado dentro de una   tipo de referencia o tipo anulable

¿Cuál es el significado de eso? Y cómo puedo solucionarlo?

¿Fue útil?

Solución

A struct es un tipo de valor, por lo que no se puede utilizar con el operador as. El operador as debe ser capaz de asignar un valor nulo si falla el reparto. Esto sólo es posible con un tipo de referencia o un tipo de valor anulable.

Hay un par de maneras de resolver esto, pero lo mejor es cambiar el tipo de Call de una estructura de una clase. Esto va a cambiar esencialmente su tipo de un tipo de valor a un tipo de referencia, que permite al operador as para asignar un valor de null si falla el reparto.

Para obtener más información sobre los tipos de valor frente a los tipos de referencia, este es un artículo decente. También, echar un vistazo en MSDN:

Otros consejos

Algunas de las respuestas existentes no son muy derecha. No se puede utilizar no anulable tipos con as, porque el resultado de as es el valor nulo del tipo si el primer operando no es en realidad de un tipo apropiado.

Sin embargo, puede as uso con los tipos de valor ... Si son anulable:

int a = 10;
object o = a;

int? x = o as int?; // x is a Nullable<int> with value 10
long? y = o as long?; // y is a Nullable<long> with the null value

Así que podría uso:

Call? call = line.Tag as Call?;

A continuación, puede utilizarlo como:

if (call != null)
{
    // Do stuff with call.Value
}

Dos advertencias aunque:

  • En mi experiencia, esto es más lento que simplemente usar is seguido por un elenco
  • Usted debe reconsiderar seriamente su tipo Call actual:
    • Se expone a campos públicos, que es generalmente pobre encapsulación
    • Es un tipo de valor mutable, lo que es casi seguro que un error

Me gustaría sugerir fuertemente que lo convierten en un lugar de clase -. Momento en el que este problema desaparece de todos modos

Otra idea: si la etiqueta debe siempre ser un Call, entonces es mejor para su emisión:

Call call = (Call) line.Tag;

De este modo, si los datos no se corresponde con sus expectativas (es decir, hay algunos errores de forma que la Tag no es un Call), entonces se llega a encontrar información sobre él temprano, en lugar de después de haber hecho potencialmente alguna otra trabajo. Tenga en cuenta que este reparto se comportan de manera diferente en función de si Call es una estructura o una clase, si es nulo Tag - usted puede echar un valor nulo a una variable de un tipo de referencia (o un tipo de valor anulable), pero no a un no tipo de valor anulable.

Desde el Spec C #

  

§7.10.11 El como operador se utiliza para   convertir explícitamente un valor de un dato    tipo de referencia o tipo anulable . A diferencia de una expresión de conversión   (§7.7.6), el operador as nunca tira   una excepción. En cambio, si el   conversión indicada no es posible,   el valor resultante es nula .

Referencias y tipos anulables puede ser nulo. Stucts son los tipos de valor para que no puedan ser nulo.

Call? call = line.Tag as Call?;

Es una limitación de C #. Si el tipo era un tipo de referencia, a continuación, si el yeso no sería simplemente volver 'nulo', pero ya que es un tipo de valor, que no sabe lo que para volver cuando la conversión falla.

Debe reemplazar su uso de, con dos: 'es' y 'como'

if (line.Tag is Call) {
  call = (Call)line.Tag;
} else {
  // Do whatever you would do if as returned null.
}

¿Cuál es el significado -. Como se ha dicho, las estructuras son tipos de valor

¿Cómo puedo resolverlo - Cambio a

Call call = line.Tag;
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top