Я просто писал настройщик свойств и имел мозговую волну о том, почему нам не нужно return
результат set
, когда свойство может быть задействовано в цепочке оператора =
, т.е.
var a = (b.c = d);
(Я добавил скобки для ясности, но на практике это не имеет никакого значения)
Я начал думать - где компилятор С# получает значение, которое присваивается a
в приведенном выше примере?
Логика говорит, что это должно быть из результата операции (b.c = d)
, но поскольку это реализовано с помощью метода void set_blah(value)
, это не может быть.
Таким образом, доступны только другие опции:
- Перечитайте
b.c
после назначения и используйте это значение -
Повторно использовать
d
-
Изменить (после ответа и комментариев от Эрика) - есть третий вариант, который является тем, что делает С#: используйте значение, записанное в
b.c
после того, как произошли какие-либо преобразования
Теперь, на мой взгляд, правильное чтение вышеуказанной строки кода
установите
a
в результат установки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);
}
Этот тест не выполняется.
Более подробное рассмотрение ИЛ, созданного для кода, показывает, что значение true
загружается в стек, клонированное командой dup
, а затем оба выпадаются в двух последовательных присваиваниях.
Этот метод отлично работает для полей, но для меня кажется ужасно наивным для свойств, где каждый на самом деле является вызовом метода, где фактическое значение конечного свойства не гарантируется как входное значение.
Теперь я знаю, что многие люди ненавидят вложенные назначения и т.д. и т.д., но факт заключается в том, что язык позволяет вам делать это, и поэтому они должны работать как ожидалось.
Возможно, я действительно толстый, но для меня это предполагает неправильную реализацию этого шаблона компилятором (.Net 4 btw). Но тогда мое ожидание/чтение кода неверно?