Присвоение свойства класса в универсальной функции

#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);