2016-11-01 3 views
0

Blick auf diesen Code:C# und Überschreibung Operator mit ref

public class classA 
{ 
    public string something; 
    public classA() 
    { 
     something = "aaa"; 
    } 
} 

public class classB 
{ 
    private classA someA = new classA(); 

    public static implicit operator classA(classB val) 
    { 
     val.someA.something = "From B"; 
     return val.someA; 
    } 

} 

ClassB enthält KlasseA, wie vereinfachte Fall. Es gibt eine Methode (Funktion, nennen Sie es, wie Sie möchten), die Klasse A als param erhalten:

public void test(classA var) 
{ 
    MessageBox.Show(var.something); 
} 

und ein anderes Verfahren, das KlasseA als ref Parameter erhalten:

public void testByRef(ref classA var) 
{ 
    MessageBox.Show(var.something); 
} 

Jetzt habe ich außer Kraft gesetzt Betreiber KlasseA in ClassB so erste Funktion kann auch mit ClassB genannt werden, aber ich weiß nicht, wie ref Operator in ClassB für zweiten Anruf außer Kraft zu setzen:

classA a = new classA(); 
    classB b = new classB(); 

    test(a); // Works 
    test(b); // Works 

    testByRef(ref a); // Works 
    testByRef(ref b); // Does not work - error CS1503: Argument 1: cannot convert from 'ref classB' to 'ref classA' 

I habe versucht, so zu überladen

und Variationen, aber mit keinem Erfolg.

Hat jemand dieses Problem und eine Lösung?

Danke, Sasa Kajic

+0

Ein Verweis auf den Rückgabewert von 'b's'-Operator classA (classB val)' ist in keiner Hinsicht ein Verweis auf 'b'. Wenn Sie so vorgehen, würde das nur Verwirrung stiften, weil die Methode, an die Sie es übergeben, einen temporären Wert ändert, der bei der Rückkehr der Methode verschwindet. Dann würden Sie hier fragen, ob wir eine Lösung für dieses Problem hätten.Es ist nicht gut für irgendjemanden, wenn etwas, das aussieht wie 'f (ref b)' ist tatsächlich 'f (lolwut)' –

+0

Wie man sieht, ist someA in ClassB nicht temporär und wird es auch nie sein. – Kajko

+0

Ich brauche Ref von B, wie ich will, dass es geändert wird und immer noch Teil von B, so trennen "Afromb" ist keine Lösung. – Kajko

Antwort

2

Sie benötigen ClassA eine Variable genau Art haben, wenn Sie es durch Verweis übergeben werden soll. Der aktuelle Wert dieser Variablen kann eine Instanz von ClassB sein, aber der Typ der Variablen muss ClassA sein.

classA a = new classA(); 
classA b = new classB(); 

testByRef(ref b); 

Das wird kompilieren. Dies muss geschehen, da testByRef dem Wert var einen Wert zuweisen kann. Dieser Wert könnte vom Typ ClassA sein, und es könnte keine Instanz ClassB sein. Daher können Sie keine Variable vom Typ ClassB bereitstellen. Der implizite Konvertierungsoperator gibt immer einen Wert zurück. Es kann keine Variable zurückgeben, was Sie mit ref in diesem Operator versuchen. Es gibt keine Möglichkeit, dies zu unterstützen.

Es ist auch erwähnenswert, dass Ihre testByRef Methode nicht tatsächlich die Variable var mutieren, so gibt es keinen Grund, es tatsächlich durch Verweis zu übergeben.

Schließlich Sie wirklich nicht tun sollen, was Sie in Ihrer ursprünglichen impliziten Operator Implementierung tun durch den Operanden mutiert, die übergeben wird, das ist extrem für Benutzer verwirrend. Ein impliziter Operator sollte eine neue Instanz des Typs erstellen, den Sie in konvertieren, ohne das ursprüngliche Objekt in irgendeiner Weise zu ändern.

+0

testbyref ist nur das, Testfunktionen. Wirkliche Funktion verändert es. – Kajko

+0

und ClassB wird per Referenz an meine 'rufenden Test'-Funktionen übergeben, so dass ich es nicht in ClassA ändern kann. – Kajko

+0

und ClassB ist so konzipiert, dass es sich je nach Zustand in diesem Moment "ändert", also "arbeiten" oder "verbinden" oder "übertragen" oder "was auch immer", mit entsprechenden Informationen und so weiter. – Kajko