2017-09-14 5 views
-1

Wenn ich initialisieren eine Variable wie folgt aus:initialisieren Variable innerhalb Methode

Nehmen wir an, wir haben:

T obj = GetT(); 

in aspx Seite. (GetT() kann Nullwert zurückgeben).
Und ich möchte, dies umgehen obj in einer Funktion

public void HandlingT(T obj){ 
    if(condition && obj == null){ 
     obj = new T(); 
    } 
    //...handling object T 
} 

So bekommen wir:

T obj = GetT(); 
HandlingT(obj); 

Das Problem ist, wenn ich die Funktion HandlingT() in aspx Seite aufrufen, obj ist immer noch null, auch wenn Die condition ist wahr

+0

Oder sollte ich stattdessen die Adresse von T in die handlingT() -Methode setzen? – kevricher

+0

Können Sie die ASPX-Seite des Codes einschließen? – combatc2

+2

Versuchen Sie 'HandlingT (out T obj)' –

Antwort

0

Sie verwechseln Verweise mit Werten. Wenn Sie dies tun:

T obj = GetT(); 
HandlingT(obj); 

Und dann innerhalb der HandlingT Methode dies zu tun:

obj = new T(); 

Der nichts auf die obj Variable tut dieser Methode außerhalb erstellt. Die Variablen haben zufällig denselben Namen, aber sie sind nicht die gleiche Variable. Sie erstellen eine Instanz von T und weisen sie der lokalen Variablen in der Methode zu. Wenn Sie diese Referenz außerhalb der Methode der Variablen zuweisen möchten, muss diese Zuordnung unter der Variablen erfolgen.

So zum Beispiel könnten Sie zurückkehren die Instanz von dem Verfahren:

public T HandlingT(T obj){ 
    if(condition && obj == null){ 
     obj = new T(); 
    } 
    return obj; 
} 

und verwendet, den Wert außerhalb des Verfahrens zurückgegeben:

T obj = GetT(); 
obj = HandlingT(obj); 

Grundsätzlich eine Zuordnung geschieht eine Variable, nicht ein In-Memory-Objekt. Wenn Sie das Objekt mit der Variablen referenzieren, können Sie dieses speicherinterne Objekt ändern. Aber wenn Sie die Variable einem neuen Objekt zuweisen, ändern Sie nicht das, worauf die Variable ursprünglich gezeigt hat, sondern Sie verweisen nur auf etwas anderes.

Bedenken Sie:

void DoSomething(MyObj obj) 
{ 
    obj = new MyObj(); 
    obj.Something = "foo"; 
} 

Das Beispiel tut nichts, um die Instanz, die ursprünglich an die Methode übergeben wurde.Eine neue Instanz wird erstellt und nur innerhalb der Methode referenziert. Sobald die Methode beendet ist, wird diese Instanz als Garbage-Collection erfasst und die ursprüngliche Instanz, die an die Methode übergeben wurde, wird nicht geändert.

Kontrast dazu:

void DoSomething(MyObj obj) 
{ 
    obj.Something = "foo"; 
} 

Da keine neue Instanz erstellt wird, die lokalen obj Variable immer noch auf die gleiche In-Memory-Instanz, die an die Methode übergeben wurde. Dieser Referenz wird gefolgt, und die ursprüngliche Instanz wird geändert, sodass die Änderung außerhalb der Methode nach Abschluss der Methode sichtbar ist.

+0

Vielen Dank @David, Sie brachten mir das, was ich nicht über orientiertes Objekt wusste – kevricher

+0

@kevricher Dies hat nichts zu tun bei objektorientierter Programmierung ist dies nur der Unterschied zwischen Wert- und Referenzsemantik. – Servy

1

Dann ändern Sie Ihre Methode, um T wie unten mit Generic zurückgeben. Im Wesentlichen Sie das Objekt erstellen, sie aber nicht zurückkehrt und somit wird es null wenn außerhalb des Funktionsumfangs

public T HandlingT<T>(T obj){ 

Wenn T ist nur ein Platzhalter für den tatsächlichen Objekt geht, dann sollten Sie nur noch wie

public T HandlingT(T obj){ 
    if(condition && obj == null){ 
     obj = new T(); 
    } 
    //...handling object T 

    return obj; 
} 
+0

Ich denke, das Generics-Bit ist nur ein Ablenkungsmanöver hier, sieht aus wie OP ist nur mit 'T' als Platzhalter für den echten Code. Auch das Ändern des Parameters auf "ref" sollte hier genug sein (obwohl ich eine Rückkehr bevorzuge, wie Sie es gewohnt sind) – DavidG

+0

@DavidG, ja sehr gut könnte sein, aber bin verwirrt mit der Verwendung von 'T' in Frage, aber sowieso der Punkt ist klar genug – Rahul

+0

Sorry für das Missverständnis mit T, hier verweise ich T auf eine Klasse, die ich erstellt – kevricher

Verwandte Themen