2013-01-31 8 views
6

Dies scheint eine sehr dumme Frage nach Gießen zu sein, aber ...„Präfix“ und „wie“ cast

Ich habe folgendes Setup:

Es gibt eine Reihe von Klassen derivces von einem Haupt Klasse. Irgendwann in Zeit und Raum bekomme ich einen Gegenstand und möchte ihn als Objekt der Unterklasse behandeln.

asume:

class subClassA : mainclass 
class subClassB : mainclass 

Jetzt habe ich einige, wenn die Klasse zu fragen, es ist:

if(someObject is subClassA) 
{ 
    subClassA aA = someObject as subClassA ; 
} 

für die meisten Subklassen das richtige Objekt Während zurückgegeben, bekomme ich für eine Subklasse eine null - Objekt.

Wenn ich Folgendes tun:

if(someObject is subClassA) 
{ 
    subClassA aA = someObject as subClassA ; // <- aA = null; someObject is shown in debugger as object of subClassA 

    object test = someObject as subClassA; // <- object is not null 
    // or 
    subClassA aB = (subClassA)someObject; // <- object is not null, shows the correct object 
} 

Ich habe Ergebnisse in test und aB.

Was ich nicht verstehe:

Warum as fehlschlagen und der Präfix Guss gelingen?


Jetzt bin ich komplett verloren.

if(someObject is subClassA) 
{ 
    subClassA aA = someObject as subClassA ; // <- aA = null; someObject is shown in debugger as object of subClassA 

    subClassA aB = someObject as subClassA ; // <- aB != null. 
} 

if(someObject is subClassA) 
{ 
    subClassA aB = someObject as subClassA ; // <- aB != null. 
} 

Der Name aA ist lokal definiert. Nur ein Thread greift auf die Methode zu. Wenn ich nur aA umbenenne, funktioniert es.

+2

Sind Sie sicher, dass 'someObject' selbst nicht' null' ist? –

+1

Das einzige, was mir einfällt, ist, dass dies mit einem verwirrten Typ zu tun hat? Wirfst du möglicherweise von einem Typ mit demselben Namen, aber einer anderen Assembly-Version? –

+0

-stanley Ich bin mir sicher, dass someobject nicht null ist - es zeigt Einträge und wird korrekt in späteren Zeilen umgewandelt @piohony kopiert und fügt den Typ aus dem is in beide anderen Erscheinungsbilder ein. Daher sollten alle 3 gleich sein. (das war der, den ich zuerst überprüft habe). Das Lustige ist, dass ich "so" benutzt habe, wie ich gelesen habe, dass "wie" bis zu 5 mal schneller sein sollte. – Offler

Antwort

1

Das Szenario, das Sie beschreiben, ist verwirrend, das zu sagen, mindestens so könnten Sie versuchen, die folgenden:

subClassA aA = (someObject as subClassA) ?? (subClassA)someObject; 

funktioniert das (zB aA nicht null)?

Sie könnten für einige Details zu as dem folgenden Post beziehen möchten:

Casting vs using the 'as' keyword in the CLR

noch einige weitere Untersuchung, aber ich bin nicht sicher, wie das Szenario neu erstellen ...

EDIT :

Eine Menge von sehr intelligenten Leuten lesen (Skeet und Lippert) versuchen, die Antwort zu finden ...

Siehe is documenation:

http://msdn.microsoft.com/en-us/library/scekt9xw(v=vs.110).aspx

as/Umwandlung Dokumentation:

http://msdn.microsoft.com/en-us/library/ms173105.aspx

+1

Ihre Charakterisierung der Beziehung zwischen ist, wie und Cast ist nicht ganz richtig. Siehe onemancat's Antwort oder meinen Artikel hier: http://blogs.msdn.com/b/ericlippert/archive/2010/09/16/is-is-as-or-is-as-is.aspx –

+0

@EricLippert I dachte ich ... die ganze Frage verwirrte mich ziemlich, wenn man annahm, dass das OP-Szenario richtig war, was es zu sein scheint, aber nicht so einfach, wie er es gesagt hat. Ich habe versucht, etwas zu beweisen, was nicht möglich ist, wenn ich stattdessen versucht hätte, das OP-Szenario zu widerlegen. Ich habe einige der Kommentare entfernt, um das Thema nicht mehr zu verwirren, als es bereits hat :) – Kelsey

+0

subClassA aA = (someObject als subClassA) ?? (subClassA) etwasObjekt; => gibt ein aA zurück, das nicht null ist. – Offler

0

Von MSDN "als" entspricht:

expression is type ? (type)expression : (type)null 

also nach MSDN, in Ihrem Code:

if(someObject is subClassA) 
{ 
    subClassA aA = someObject as subClassA ; 
} 

äquivalent zu

if(someObject is subClassA) 
{ 
    subClassA aA = someObject is subClassA ? (subClassA)someObject : (subClassA)null ; 
} 

Da someObject is subClassA auf beiden Leitungen erscheint, das einzige, was ich denken konnte, würde entweder sein, dass 1) someobject ist tatsächlich in einigen Fällen null; oder 2) Sie haben eine Multithread-Anwendung und Ihr Code ist nicht threadsicher (dh von Zeit zu Zeit ist die "ist" -Zeile wahr, aber zu dem Zeitpunkt, zu dem die "as" -Zeile erreicht wird, ist das implizite "" "ist falsch geworden."

+2

Sie können nicht "null" haben, aber mit einem Typ kompatibel ". Es gibt nur eine "Null". – svick

+0

1) Ich gehe den Code Schritt für Schritt durch. Das Objekt someObject ist vor der Umwandlung "as" nicht null, und nach der Umwandlung ist someObject nicht null. 2) sicher ist es eine Multithread-Anwendung. Aber: a) warum soll das nur mit einem "as" Cast passieren und nicht mit den anderen (und immer mit dem einen) b) in parallellem Task View verwende ich keinen anderen Thread, der weder Objekt noch Methode verwendet, das Objekt ist nur Build innerhalb eines Threads und Zugriff von ihm. c) die Aussage von Kelsey "Xa = (irgendeinObjekt als X) ?? (X) irgendeinObjekt;" zeigt das korrekte Ergebnis an. (oder die "(subClassA)" -Anweisung nach der "as" -Anweisung. – Offler

0

Während in den meisten Fällen das korrekte Objekt zurückgegeben wird, bekomme ich manchmal ein Null-Objekt.

Es gibt nur eine einfache Erklärung für Ihr Problem. Die someObject Referenz wird von einem anderen Thread geändert. Sie müssen die Sperre Anweisung verwenden, um es zu schützen.

+0

das someObject wird innerhalb des Threads erstellt, der es verbraucht. Auch wenn ich in den Debugger sehe, sehe ich keine Änderungen am someobject. Ich meinte mit den meisten Fällen: es ist eine Form wenn (Objekt ist A) {} sonst wenn (Objekt ist B) {} sonst wenn (... die meisten Fälle funktionieren, aber nur ein Baum "wenn (Objekt ist B)" funktioniert nicht. In der Fall, wo es nicht funktioniert, kann ich das richtige Objekt mit der Aussage von Kelsey Post (subClassA aA = (someObject als subClassA) ?? (subClassA) someObject;), aber nicht mit der Verwendung von "as" – Offler