Frage

I definiert die folgende Struktur:

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

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

Später habe ich es an die Tag-Eigenschaft eines anderen Objekts zuweisen:

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

Aber wenn ich versuche, die Tag-Eigenschaft abzurufen wie so,

Call call = line.Tag as Call;

Visual Studio gibt folgende Fehler bei der Kompilierung:

  

Der Betreiber wie muss innerhalb einer verwendet werden   Referenztyp oder Nullable Type

Was bedeutet das? Und wie kann ich es lösen?

War es hilfreich?

Lösung

Eine Struktur ist ein Werttyp, so dass es nicht mit dem as Operator verwendet werden kann. Der as Betreiber müssen einen Wert von Null zugewiesen werden, wenn die Umwandlung fehlschlägt. Dies ist nur möglich mit einem Referenztyp oder einem Nullable-Wertetyp.

Es gibt ein paar Möglichkeiten, dies zu lösen, aber die beste Wahl ist Ihre Call Typ von einer Struktur zu einer Klasse zu ändern. Dies wird im Wesentlichen Ihre Art von einem Werttyp auf einen Referenztyp ändern, die der as Operator ermöglicht einen Wert von Null zugewiesen werden, wenn die Umwandlung fehlschlägt.

Weitere Informationen über die Werttypen vs. Referenztypen dieser ist ein anständiger Artikel. Außerdem haben Sie einen Blick auf MSDN:

Andere Tipps

Einige der vorhandenen Antworten sind nicht ganz rechts. Sie können nicht mit Nicht-Nullable Typen mit as, weil das Ergebnis as der Nullwert des Typs ist, wenn der erste Operand nicht tatsächlich einen geeigneten Typs ist.

Allerdings Sie können Verwendung as mit Werttypen ... Wenn sie auf NULL festlegbare:

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

So Sie könnte Verwendung:

Call? call = line.Tag as Call?;

Dann können Sie es als verwenden:

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

Zwei Vorbehalte aber:

  • Nach meiner Erfahrung ist dies langsamer als nur mit is von einer Besetzung gefolgt
  • Sie sollten ernsthaft Ihre aktuelle Call Art überdenken:
    • Es ist auszusetzen öffentliche Felder, die in der Regel eine schlechte Kapselung ist
    • Es ist ein veränderlicher Werttyp, die mit ziemlicher Sicherheit ein Fehler ist

Ich würde dringend empfehlen, es sich um eine Klasse zu machen, statt -. An welcher Stelle dieses Problem geht sowieso weg

Ein anderer Gedanke: Wenn der Tag sollte immer einen Call sein, dann ist es besser, es zu werfen:

Call call = (Call) line.Tag;

Auf diese Weise, wenn die Daten nicht Ihren Erwartungen nicht entspricht (dh es gibt einige Fehler, so dass die Tag ist kein Call), dann Sie es, um herauszufinden, früh, anstatt, nachdem Sie möglicherweise einige andere getan haben Arbeit. Beachten Sie, dass diese Besetzung anders auf verhalten wird je nachdem, ob Call ist eine Struktur oder eine Klasse, wenn Tag null ist - Sie einen Nullwert auf eine Variable eines Referenztyp (oder einem Nullable-Wertetyp) abgeben können, aber nicht zu einer nicht Nullable-Wertetyp.

Von dem C # Spec

  

§7.10.11 Der als Operator wird verwendet, um   explizit konvertieren Wert auf einen bestimmten    Referenztyp oder Nullable Type . Im Gegensatz zu einem gegossenen Ausdruck   (§7.7.6), nie die als Betreiber wirft   eine Ausnahme. Stattdessen, wenn die   angegebene Umwandlung nicht möglich ist,   der resultierende Wert null .

Referenzen und Nullable-Typen können null sein. Stucts sind Werttypen, so dass sie nicht null sein kann.

Call? call = line.Tag as Call?;

Es ist eine Einschränkung von C #. Wenn der Typ ein Referenztyp war, dann, wenn die Besetzung gescheitert wäre es einfach zurückgeben ‚Null‘, aber da es ein Werttyp ist, weiß er nicht, was zurückzukehren, wenn die Umwandlung fehlschlägt.

Sie müssen Ihre Verwendung als mit zwei ersetzen: ‚ist‘ und ‚wie‘

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

Was ist die Bedeutung -. Wie bereits erwähnt, Strukturen sind Wertetypen

Wie kann ich es lösen - ändern Sie ihn auf

Call call = line.Tag;
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top