Никогда не приходил в голову вопрос: "
а как сохранить/передать в другой поток ссылку на поле?"? Логичным предположением будет «передам ref в метод и сохраню. Стоп, oh shi~». Да,
ref не сохраняются (а ещё, нельзя использовать на них замыкания, так что создать функцию внутри такого метода и создать из её поток тоже не получится). Но зато можно превратить
ref в
TypedReference с помощью недокументированного ключевого слова
__makeref. Увы,
TypedReference нельзя напрямую сохранить в поле и
не наследует от
System.Object, так что каст привычными методами тоже невозможен (да и вообще на их использование наложена целая куча ограничений). Казалось бы, тупик. Но это ещё не всё — есть ещё
RuntimeArgumentHandle, который обладает свойствами
TypedReference, за одним исключением — после хитрого каста в
System.Object его ещё можно использовать до тех пор, пока жив кадр стека, в котором он был создан. Об этом этот пост.