Непонимание C # class vs struct

#c# #lambda #copy

#c# #лямбда #Копировать

Вопрос:

Я пытался реализовать автоматическую дифференциацию C # lib на основе примера Python, но у меня проблема с функцией lambda / local (довольно расплывчато, не уверен, почему она не работает). Я даже успешно реализовал это на другом языке: Kotlin … Так что у меня, вероятно, есть недопонимание какой-то части программирования, либо что-то связанное с узким / глубоким копированием, либо с лямбда / локальной функцией.

 public static Value operator  (Value a, Value b)
{
    var ret = new Value(a.Data   b.Data, new[]{a, b});

    void B()
    {
        a.Gradient  = ret.Gradient;
        b.Gradient  = ret.Gradient;
    }

    ret._backward = B;
    return ret;
}
  

Я привожу этот небольшой фрагмент кода, но лучше посмотреть на весь: полный код с тестами на 3 языках

Градиент странно не меняется, я не знаю, как лучше объяснить проблему.

Комментарии:

1. Пожалуйста, помечайте вопросы только тем языком, о котором вы спрашиваете, а не другими языками, которые упоминаются в качестве примеров.

Ответ №1:

Попробуйте изменить Value struct значение, т.е. тип значения class , на ссылочный тип:

 public class Value
{
    ...
}
  

Как указано в документах:

Переменная типа значения содержит экземпляр этого типа. Это отличается от переменной ссылочного типа, которая содержит ссылку на экземпляр типа. По умолчанию при присваивании, передаче аргумента методу и возврате результата метода значения переменных копируются. В случае переменных типа значения копируются соответствующие экземпляры типа

таким образом, изменения полей локальной a и b внутренней operator функции не повлияют на внешние значения.

Комментарии:

1. Боже, спасибо! Застрял на этом некоторое время, понял… использование класса правильно обновляет градиент по ссылке

2. @LouisBeaumont был рад помочь!