#c# #lambda
#c# #лямбда
Вопрос:
У меня есть следующий код.
A a = new A(....); .... a.Prop1 = ...
B b = new B(....); .... b.Prop1 = ...
DoSth(a.Prop1, b.Prop1);
void DoSth<T>(T curr, T prev)
{
if (!EqualityComparer<T>.Default.Equals(curr, prev))
{
prev = curr; // prev changed, however b is not changed.
....
callSomeFn(b);
.....
}
Передача присваивающего лямбда-выражения должна работать.
void DoSth<T>(T curr, T prev, Action assign)
{
if (!EqualityComparer<T>.Default.Equals(curr, prev))
{
assign();
.....
}
DoSth(a.Prop1, b.Prop1, ()=>a.Prop1 = b.Prop1);
Однако это выглядит довольно громоздко. Есть ли лучший способ сделать это? ( ref
не может использоваться для свойств объекта.)
Ответ №1:
Давайте разберем обобщения. Предположим, что тип — int . У вас было бы:
void DoSth(int curr, int prev)
{
if (!EqualityComparer<int>.Default.Equals(curr, prev))
{
prev = curr;
.....
}
DoSth(a.Prop1, b.Prop1);
Почему вы ожидаете, что «prev = curr» повлияет на что-либо, выходящее за рамки метода? Вы присваиваете одной локальной переменной значение другой локальной переменной.
Предполагая, что это на самом деле то, что вы хотите, я подозреваю, что вы хотите использовать ключевое слово ref для параметров.
Комментарии:
1.
ref
не может использоваться для свойств объекта.2. @terrybozzio Так
var bProp1 = b.Prop1; DoSth(a.Prop1, ref bProp1);
должно работать, как ожидалось? (Функция будетvoid DoSth<T>(T curr, ref T prev) {....}
)
Ответ №2:
Возможно, я слишком упрощаю это, но разве что-то подобное не сработает?
T DoSth<T>(T curr, T prev)
{
if (!EqualityComparer<T>.Default.Equals(curr, prev))
{
return curr;
}
return prev
}
a.Prop1 = DoSth(a.Prop1, b.Prop1);
Комментарии:
1.
DoSth
будет использоватьсяb
вif
блоке. Поэтому я не могу написать функцию таким образом. Я обновил вопрос.2. Итак, измените подпись, чтобы взять a и b и вызвать
a.Prop1 = DoSth(a, b);