Я пытаюсь создать делегатов для доступа к любым методам получения и установки свойств.
Я нашел следующий код (в этом посте: driis о глубоких свойствах ), который работает очень хорошо:
public static class Extractor<TObject> where TObject : class
{
public static DelegateAccessor<TObject, TValue> GetAccessorsDelegates<TValue>(Expression<Func<TObject, TValue>> expression)
{
Func<TObject, TValue> getter = expression.Compile();
ParameterExpression pObj = expression.Parameters[0];
ParameterExpression pValue = Expression.Parameter(typeof(TValue), "value");
BlockExpression setterBlock = Expression.Block(Expression.Assign(expression.Body, pValue));
Expression<Action<TObject, TValue>> setterExpression = Expression.Lambda<Action<TObject, TValue>>(setterBlock, pObj, pValue);
Action<TObject, TValue> setter = setterExpression.Compile();
return new DelegateAccessor<TObject, TValue>(getter,setter);
}
}
Например: когда я создаю установщик из параметра «Выражение в», я получаю своих делегатов получателя и установщика, например:
get : (t => t.ID)
set : (t, value) => { t.ID = value}
Моя проблема с такими индексаторами:
public object this[int id]
Когда я вызываю подчиненное свойство индексатора, проблем не возникает. Он работает нормально, так как доступ к индексатору с внутренним именем «Item» можно получить, прочитав его:
Extractor<MyObject>.DelegateAccessor(t => t.MySubTable[2].MyProperty)
выражение:
t => t.MySubTable.get_Item(2).MyProperty
Но я не могу найти способ получить внутреннее сеттерное выражение. Моя цель - получить что-то вроде этого:
(t, value) => { t.MySubTable.set_Item(2, value) }
Но я не могу использовать назначение с лямбдой, как этот:
(t,v) => t.SubStrings[0] = v
Я получаю сообщение об ошибке CS0832: Дерево выражений может не содержать оператор присваивания.
Есть ли способ написать лямбда-выражение, чтобы найти тело "set_Item (2, value)" в параметре Expression> ???
Заранее спасибо, я знаю, что это сложный вопрос ...