3

次のシグネチャを持つメソッドを想像してください。

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

の値に応じて、 の値を、、または何もdata割り当てない必要があります。要するに、もしそうならABCidid == "A"A = data;

問題は、このメソッドの本体が人間によって型付けされているのに、署名が実行時に生成されることです。このため、設計時に ref パラメーターがいくつあり、それらが何と呼ばれるかが不明であるため、ロジックをハードコーディングすることはできません。このコード片は、任意の数のメソッドに挿入でき、それぞれが異なる署名を持つ可能性があり、すべてのメソッドで機能する必要があります。

現在使用されているメソッドのすべてのパラメーターを取得する方法は知っていますが、これらのパラメーターの 1 つに値を割り当てる方法がわかりません。私が探しているのは、次のようなものです。

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;
    }
  }
}
4

1 に答える 1

2

変数/パラメーターでリフレクションを実際に使用できないため、名前でパラメーターにアクセスすることはできません。これが IL の場合はいくつかのオプションがあるかもしれませんが、実際には C# ではありません。私のアドバイスは次のとおりです。APIを変更します。おそらく、配列または(おそらくより良い)辞書のいずれかを含むものです。検討:

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

それが役立つかどうかはわかりません...しかし、あなたがやろうとしていることは、実際にはリフレクションフレンドリーではありません. もう 1 つのオプションは、ビルド プロセスの一部として、または IL を介して、このメソッドを動的に生成することです。どちらでもいいはずです。したがって、基本的に(C#または(実行時に)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 */
    }
}

追加のアプローチ: 型指定されたオブジェクト: あなたが持っているとしましょう:

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

ここobjで、「A」、「B」、「C」などのプロパティを持つオブジェクトです。次に、生成しようとしているものは次のとおりです。

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

もちろん、これはリフレクションで行うことができます:

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

または、パフォーマンスが重要な場合は、fast-member のようなもの:

var wrapped = ObjectAccessor.Create(obj); 
wrapped[id] = data;
于 2012-02-29T09:47:54.943 に答える