Frage

Ich bin Tring eine Bibliothek bauen simplifing späte Bindung Anrufe in C #, und ich Mühe, mit Bezug parameteres Tring. Ich habe die folgende Methode einen Parameter in einem Methodenaufruf

verwendet hinzufügen
    public IInvoker AddParameter(ref object value)
    {
        //List<object> _parameters = new List<object>();
        _parameters.Add(value);          

        //List<bool> _isRef = new List<bool>();
        _isRef.Add(true);

        return this;
    }

Und das mit Werttyp nicht funktioniert, weil sie als Objekt verpackt bekommen, so werden sie nicht geändert. Z. B:

int param1 = 2;
object paramObj = param1;
//MulFiveRef method multiplies the integer passed as a reference parameter by 5:
//void MulFiveRef(ref int value) { value *= 5; }
fi.Method("MulFiveRef").AddParameter(ref paramObj);

Das funktioniert nicht. Der späte Bindung Aufruf erfolgreich ist, und die innere Liste, die die parameteres (_parameters) hält nicht geändert, aber nicht den Wert außerhalb des Anrufs.

Hat jemand eine einfache Möglichkeit, kennt diese Einschränkung zu überwinden? Die AddParameter Signatur kann nicht geändert werden, da mit der späten Bindung Anrufe, Sie nicht im Voraus die Art der Parameter kennen, können (und so oder so alle Parameter für einen Anruf innerhalb eines Objekts Array einfügen, bevor der Anruf zu machen)

Vielen Dank im Voraus.

War es hilfreich?

Lösung

Wenn der Wert ändert innerhalb der Methode , müssen Sie eine temporäre (object) Variable deklarieren, um die Methode zu übergeben (ref) und unbox es sich danach:

    int i = 3;
    //...
    object obj = i;
    Foo(ref obj);
    i = (int)obj;

Beachten Sie, dass dies nicht zulassen, dass der Wert nach dem Ereignisse zu aktualisieren. So etwas wie ein Ereignis oder Rückruf könnte eine alternative Möglichkeit der Weitergabe Änderungen wieder an den Aufrufer.

Beachten Sie auch, dass C # 4.0 ein paar Tricks hat mit diesem nur helfen im Zusammenhang mit der COM-Aufrufe ([zuzüglich natürlich ref object für die späte Bindung, wie Jon bemerkt] wo dynamic so üblich ist).

Andere Tipps

Ihre Methode ändert value sowieso nicht - warum sind vorbei Sie es als Referenz? Es kann sinnvoll sein, aber es ist nicht wirklich klar zu mir. Beachten Sie, dass der Beispielcode Sie zur Verfügung gestellt haben sowieso nicht kompilieren würde, als ref Argumente sein müssen genau vom gleichen Typ wie der Parameter.

(Auch Sie sind sich bewusst, dass C # 4.0 und .NET 4.0 wird haben eine integrierte Unterstützung für späte Bindung? Die Chancen stehen gut, dass die Sprache integrierte Version leichter sein wird als eine Bibliothek-nur zu verwenden. Sind Sie sicher, es lohnt sich Zeit für die Bibliothek zu diesem Zeitpunkt zu verbringen?)

EDIT: Der Code, den Sie wirklich kompilieren wird nicht zur Verfügung gestellt haben. Sie erhalten nicht Boxen für ref Parameter, gerade weil die Argumentation und Parametertypen genau das gleiche sein. Hier ist ein Beispielcode, um es zu beweisen:

public class Test
{
    static void Main()
    {
        int i;
        Foo(ref i); // Won't compile - error CS1502/1503
    }

    static void Foo(ref object x)
    {
    }
}

Wenn Ihr aktueller Code ist kompiliert, dann ist es nicht der Code, den Sie in der Frage vorgelegt. Vielleicht haben Sie eine weitere Überlastung für AddParameter die ref int akzeptiert?

Ok, dank Jon Skeet Korrekturen und Mark GRA-Code, ich habe mit dieser Schnittstelle kommen:

        //This will be created with a factory
        IOperationInvoker invoker = new OperationInvoker(Activator.CreateInstance<MyLateBindingTestType>());

        int param1 = 2;
        object paramObj = param1;

        invoker.AddParameter(ref paramObj).Invoke("MulFiveRef");

        param1 = (int)invoker.Parameters[0];

Ist das nicht genau so, wie ich es mir vorgestellt habe, aber ist viel einfacher und lesbar, dass meine vorherige Schnittstelle:

        IOperationInvoker invoker = new OperationInvoker(Activator.CreateInstance<MyLateBindingTestType>());
        int refValue = 10;
        object[] args = Args.Build(refValue);

        invoker.Call("MulFiveRef", Args.ByRefIndexs(0), args);

        refValue = (int)args[0];

Vielen Dank für Ihre Hilfe Menschen:)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top