Domanda

I definito il seguente struct:

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

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

In seguito, ho assegnare alla proprietà Tag di un altro oggetto:

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

Ma quando cerco di recuperare la proprietà Tag in questo modo,

Call call = line.Tag as Call;

Visual Studio dà il seguente errore in fase di compilazione:

  

L'operatore deve essere utilizzato entro un   tipo di riferimento o tipo nullable

Qual è il significato di questo? E come posso risolverlo?

È stato utile?

Soluzione

Una struct è un tipo di valore, pertanto non può essere utilizzato con l'operatore as. L'operatore as deve essere in grado di assegnare un valore nullo se il cast fallisce. Questo è possibile solo con un tipo di riferimento o un tipo valore nullable.

Ci sono un paio di modi per risolvere questo, ma la cosa migliore è cambiare il tipo di Call da una struttura a una classe. Ciò essenzialmente modificare il tipo da un tipo di valore di un tipo di riferimento, che permette all'operatore as assegnare un valore nullo se il cast fallisce.

Per ulteriori informazioni sui tipi di valore rispetto a tipi di riferimento, questo è un articolo decente. Inoltre, avere uno sguardo su MSDN:

Altri suggerimenti

Alcune delle risposte esistenti non sono molto a destra. Non è possibile utilizzare non annullabili tipi con as, perché il risultato del as è il valore nullo del tipo, se il primo operando non è in realtà di un tipo appropriato.

Tuttavia, è possono uso as con i tipi di valore ... se sono annullabili:

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

potrebbe uso:

Call? call = line.Tag as Call?;

Quindi è possibile utilizzare come:

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

Due avvertimenti però:

  • Nella mia esperienza, questo è più lento di solo usando is seguito da un cast
  • Si dovrebbe seriamente riconsiderare il tipo di Call corrente:
    • E 'esponendo campi pubblici, che è generalmente scarsa incapsulamento
    • Si tratta di un tipo di valore mutevole, che è quasi certamente un errore

Vorrei suggerire si rendono una classe invece -. A questo punto il problema va via comunque

Un altro pensiero: se il tag deve sempre essere un Call, allora è meglio per lanciarla:

Call call = (Call) line.Tag;

In questo modo, se i dati non corrisponde a vostra aspettativa (cioè c'è qualche bug in modo tale che il Tag non è un Call) poi si arriva a scoprire presto, piuttosto che dopo aver fatto qualche altro potenzialmente lavoro. Si noti che questo cast si comporterà in modo diverso a seconda che Call è una struttura o una classe, se Tag è nullo - si può lanciare un valore null a una variabile di un tipo di riferimento (o di un tipo di valore nullable), ma non a un non- nullable tipo di valore.

Dalla C # Spec

  

Il §7.10.11 come operatore viene utilizzato per   convertire in modo esplicito un valore ad un determinato    tipo di riferimento o tipo nullable . A differenza di un'espressione getto   (§7.7.6), l'operatore as mai getta   un'eccezione. Al contrario, se il   conversione indicata non è possibile,   il valore risultante è Null .

Riferimenti e tipi nullable possono essere nulli. Stucts sono tipi di valore in modo che non possono essere nulli.

Call? call = line.Tag as Call?;

Si tratta di una limitazione di C #. Se il tipo fosse un tipo di riferimento, quindi se il cast non è riuscita sarebbe semplicemente tornare 'nulla', ma dal momento che è un tipo di valore, ma non sa cosa per tornare quando il cast non riesce.

È necessario sostituire l'uso di come con due: 'è' e 'come'

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

Qual è il significato -. Come detto, le strutture sono tipi di valore

Come posso risolverlo - Variazione su

Call call = line.Tag;
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top