メソッドパラメータに値を割り当てます
-
14-11-2019 - |
質問
以下の署名を備えた方法を想像してみてください:
public void ExampleMethod(string id, object data,
ref object A, ref object B, ref object C)
{
//...
}
.
data
の値に応じて、A
、B
、C
、またはNothingに割り当てる必要があります。要するに、id
がid == "A"
の場合
問題は、このメソッドの本体が人間によって入力されるが、署名は実行時に生成されることである。このため、デザイン時には不明な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;
}
}
}
. 解決
変数/パラメータの反射を実際に使用することはできないので、名前でパラメータにアクセスすることはできません。これがILの場合はいくつかのオプションがあるかもしれませんが、実際にはC#ではありません。私のアドバイスは次のようになります.APIを変更してください。検討してください:
public void ExampleMethod(string id, object data,
IDictionary<string,object> args) {
args[id] = data;
}
.
それが役立つかどうかはわかりません...しかし、あなたがやろうとしていることは実際には反映されません。もう1つのオプションは、このメソッドをビルドプロセスの一部として、またはILを介して動的に生成することです。どちらも大丈夫です。それで、それは基本的に生成される可能性があります(C#または(実行時)):
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;
.