Код: Выделить всё
var a = (b.c = d);
Я начал думая: откуда компилятор C# получает значение, присвоенное в приведенном выше примере?
Логика подсказывает, что оно должно быть получено из результата (b.c = d), но поскольку она реализована с помощью метода void set_blah(value), это невозможно.
Так что единственный другие варианты:
- Перечитать b.c после присваивания и использовать это значение
< li>Повторно использовать d - Изменить (поскольку Эрик ответил и оставил комментарии) - есть третий вариант, который и делает C#: используйте значение, записанное в b.c после выполнения любых преобразований
set a< /code> в результат установки b.c в d
Я думаю, что это разумное прочтение код - поэтому я решил проверить, действительно ли это происходит, с помощью слегка надуманного теста - но спросите себя, считаете ли вы, что он должен пройти или не пройти:
Код: Выделить всё
public class TestClass
{
private bool _invertedBoolean;
public bool InvertedBoolean
{
get
{
return _invertedBoolean;
}
set
{
//don't ask me why you would with a boolean,
//but consider rounding on currency values, or
//properties which clone their input value instead
//of taking the reference.
_invertedBoolean = !value;
}
}
}
[TestMethod]
public void ExampleTest()
{
var t = new TestClass();
bool result;
result = (t.InvertedBoolean = true);
Assert.IsFalse(result);
}
Более тщательное изучение IL, созданного для код показывает, что значение true загружается в стек, клонируется с помощью команды dup, а затем оба значения извлекаются двумя последовательными присваиваниями.
Этот метод отлично работает для полей, но мне кажется ужасно наивным для свойств, каждое из которых на самом деле является вызовом метода, где фактическое конечное значение свойства не гарантированно является входным значением.
Я знаю, что многие люди ненавидят вложенные задания и т. д. и т. п., но факт в том, что язык позволяет вам их выполнять, и поэтому они должны работать так, как ожидается.
Возможно Я очень тупой, но для меня это предполагает неправильную реализацию этого шаблона компилятором (кстати, .Net 4). Но тогда мои ожидания/чтение кода неверны?
Подробнее здесь: https://stackoverflow.com/questions/666 ... hould-pass
Мобильная версия