Ответ 1
Вероятно, вы говорите о предупреждении CS1690, воспроизводите код:
public class Remotable : MarshalByRefObject {
public int field;
}
public class Test {
public static void Run() {
var obj = new Remotable();
// Warning CS1690:
Console.WriteLine(obj.field.ToString());
}
}
В удаленном сценарии метод Test.Run будет работать с прокси-сервером объекта Remotable. Построение прокси-сервера для свойства, метода или события не является большой проблемой, а просто создаёт MethodTable, который содержит заменители. Поля - проблема, однако ничего не стоит "зацепить". Для MBRO компилятор JIT больше не генерирует код для прямого доступа к полю, он в этом случае вызывает вызов вспомогательного метода, встроенного в CLR, JIT_GetField32().
Этот помощник проверяет, является ли объект прокси-сервером, и использует удаленную сантехнику для получения удаленного значения, если это случай. Или просто обращается к полю напрямую, если это не так. Однако для вызова ToString() требуется ввести значение. В этой проблеме бокс изолирует значение от прокси. Невозможно гарантировать, что значение в штучной упаковке всегда является точной копией удаленного значения. Вызов JIT_GetField32() снова, когда метод ToString() использует значение для форматирования строки, невозможно.
Обходной путь для CS1690 прост, за исключением поля с свойством, просто скопируйте значение поля в локальную переменную. Теперь совершенно ясно, что код работает с копией, и никогда не бывает сюрпризов, поэтому компилятору не придется выдавать предупреждение.
public static void Run() {
var obj = new Remotable();
var value = obj.field;
Console.WriteLine(value.ToString()); // No warning
}