Присвойте значение параметру метода
Представьте себе метод со следующей подписью:
public void ExampleMethod(string id, object data,
ref object A, ref object B, ref object C)
{
//...
}
Значение в data
должен быть назначен либо A
, B
, C
или ничего, в зависимости от значения id
, Короче если id == "A"
затем A = data;
Проблема в том, что тело этого метода набрано человеком, но подпись генерируется во время выполнения. Из-за этого невозможно жестко закодировать логику, потому что во время разработки неизвестно, сколько будет параметров ref и как они называются. Этот кусок кода может быть вставлен в любое количество методов, каждый из которых может иметь свою подпись, и он должен работать в каждом из них.
Я знаю, как получить все параметры метода, в котором находится в данный момент, но я не могу понять, как присвоить значение одному из этих параметров. Я ищу что-то вроде следующего:
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;
}
}
}
1 ответ
Вы не можете получить доступ к параметрам по имени, так как вы не можете использовать отражение переменных / параметров. У вас могут быть некоторые варианты, если это был IL, но не совсем в C#. Мой совет: измените API, возможно, что-то, включающее либо массив, либо (возможно, лучше) словарь. Рассматривать:
public void ExampleMethod(string id, object data,
IDictionary<string,object> args) {
args[id] = data;
}
Не уверен, поможет ли это... но то, что вы пытаетесь сделать, не очень благоприятно для размышлений. Другой вариант - генерировать этот метод динамически, либо как часть вашего процесса сборки, либо через 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;