Суть в том, что для метода на struct
значение this
- это не значение (т. Е. Значение вашего SomeStruct
), а скорее ссылка (ref SomeStruct
или, по сути, in SomeStruct
в случае readonly struct
).
Вы не можете пометить управляемый указатель этой формы - это неСценарий поддерживается во время выполнения.Управляемые указатели предназначены только для стека.Фактически, в настоящее время вы не можете даже иметь поле ref SomeStruct
в пользовательском ref struct
, которое не может выйти из стека.
Компилятор может обмануть путем притворства для этого - то есть путем разыменования управляемого указателя из ref SomeStruct
в SomeStruct
и создания контекста захвата, где this
интерпретируется как "SomeStruct
, который мы разыменовали ранее", но ... тогда компилятор не может гарантировать такое же поведение и результаты (на самом деле, я подозреваю, что для этого можно было бы сделать сценарий readonly struct
, но ... вероятно, легче не вводить этот тонкийРазличие).
Вместо этого, компилятор предлагает вам эффективно выполнить вышеуказанный шаг вручную ;поскольку компилятор больше не работает в терминах this
, ему больше не нужно притворяться, что он уважает обычные результаты для работы с this
, и вместо этого он должен только гарантировать поведение явно разыменованной копии стоимости.Вот почему он советует (по крайней мере, в текущих версиях компилятора):
Попробуйте скопировать 'this' в локальную переменную вне анонимного метода, лямбда-выражения или выражения запроса и использовать вместо этого локальный.
Большинство лямбд, локальных методов и т. Д., Следовательно, могут быть достигнуты с помощью прагматического шага:
MyStruct copy = this; // dereference
затем в вашем лямбда / локальном методе / etc: вместо касания Something
aka this.Something
- коснитесь copy.Something
.Теперь только copy
включается в контекст захвата, и copy
не связан правилами ref SomeStruct
(потому что: это не ref SomeStruct
- это SomeStruct
).
Это означает , однако, означает, что если ваше намерение было мутировать this
(и иметь этот видимый на месте , скореечем в качестве возвращаемого значения), то это не будет работать.Вы будете только мутировать копию (то есть copy
).Это именно то, что компилятор должен был бы сделать в любом случае , если бы он солгал, но, по крайней мере, теперь шаг копирования (разыменование) является явным и видимым в вашем коде.