Frage

Stellen Sie sich eine Methode mit der folgenden Signatur vor:

public void ExampleMethod(string id, object data, 
                          ref object A, ref object B, ref object C)
{
  //...
}

Der Wert in data muss einem von beiden zugewiesen werden A, B, C oder nichts, abhängig vom Wert von id.Kurz gesagt, wenn id == "A" Dann A = data;

Das Problem besteht darin, dass der Hauptteil dieser Methode von einem Menschen eingegeben wird, die Signatur jedoch zur Laufzeit generiert wird.Aus diesem Grund ist es nicht möglich, die Logik fest zu codieren, da zur Entwurfszeit nicht bekannt ist, wie viele Ref-Parameter es geben wird und wie sie heißen.Dieses Stück Code kann in eine beliebige Anzahl von Methoden eingefügt werden, jede möglicherweise mit einer anderen Signatur, und es muss in jeder einzelnen funktionieren.

Ich weiß, wie ich alle Parameter der Methode erhalte, in der man sich gerade befindet, aber ich kann nicht herausfinden, wie ich einem dieser Parameter einen Wert zuweisen kann.Was ich suche, ist etwa Folgendes:

public void ExampleMethod(string id, object data, 
                          ref object A, ???????, ref object Z)
{
  MethodBase method = MethodBase.GetCurrentMethod();
  foreach (ParameterInfo parameter in method.GetParameters())
  { 
    if (id == parameter.Name)
    {
      // Problem: assign data to parameter.
      return;
    }
  }
}
War es hilfreich?

Lösung

Sie können nicht über den Namen auf Parameter zugreifen, da Sie die Reflektion für Variablen/Parameter nicht wirklich verwenden können.Wenn dies IL wäre, hätten Sie möglicherweise einige Optionen, aber nicht wirklich in C#.Mein Rat wäre:Ändern Sie die API, vielleicht etwas, das entweder ein Array oder (vielleicht besser) ein Wörterbuch beinhaltet.Halten:

public void ExampleMethod(string id, object data,
        IDictionary<string,object> args) {
    args[id] = data;
}

Ich bin mir nicht sicher, ob das hilft ...Aber was Sie versuchen, ist nicht wirklich reflexionsfreundlich.Die andere Möglichkeit besteht darin, diese Methode dynamisch zu generieren, entweder als Teil Ihres Build-Prozesses oder über IL.Beides sollte in Ordnung sein.Es könnte also im Wesentlichen Folgendes generieren (entweder als C# oder (zur Laufzeit) IL):

public void ExampleMethod(string id, object data, 
                          ref object A, ref object B, ref object C)
{
    switch(id) {
        case "A": A = data; break;
        case "B": B = data; break;
        case "C": C = data; break;
        default: /* do something */
    }
}

Ein zusätzlicher Ansatz:das eingegebene Objekt:sagen Sie, Sie haben:

public void ExampleMethod(string id, object data, SomeType obj) {...}

Wo obj ist ein Objekt mit Eigenschaften wie „A“, „B“, „C“;Dann versuchen Sie Folgendes zu generieren:

switch(id) {
    case "A": obj.A = data; break;
    case "B": obj.B = data; break;
    case "C": obj.C = data; break;
    default: /* do something */
}

was natürlich mit Reflexion geschehen kann:

var prop = obj.GetType().GetProperty(id);
prop.SetValue(obj, data, null);

oder wenn die Leistung entscheidend ist, so etwas wie Fast-Mitglied:

var wrapped = ObjectAccessor.Create(obj); 
wrapped[id] = data;
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top