Ok, это может быть очевидным для некоторых из вас, но я озадачен поведением я получаю от этого достаточно простого кода:Не понимаю заранее поведение оператора декремента с типом Nullable
public static void Main(string[] args)
{
int? n = 1;
int i = 1;
n = ++n - --i;
Console.WriteLine("Without Nullable<int> n = {0}", n); //outputs n = 2
n = 1;
i = 1;
n = ++n - new Nullable<int>(--i);
Console.WriteLine("With Nullable<int> n = {0}", n); //outputs n = 3
Console.ReadKey();
}
I exepcted оба выхода должны быть одинаковыми и равными 2
, но, как ни странно, это не так. Может кто-нибудь объяснить, почему?
EDIT: Хотя код для создания этого «странного» поведения, по общему признанию надуманный, это выглядит как ошибка в C# компилятора, хотя, казалось бы, неважные и причина, кажется, встраиваемыми new
, как James указывал на начальном этапе. Но поведение не ограничивается операциями. Вызовы метода ведут себя точно так же, т. Е. Их вызывают дважды, когда их нужно вызывать только один раз.
Рассмотрим следующий репро:
public static void Main()
{
int? n = 1;
int i = 1;
n = n - new Nullable<int>(sideEffect(ref i));
Console.WriteLine("With Nullable<int> n = {0}", n);
Console.ReadKey();
}
private static int sideEffect(ref int i)
{
Console.WriteLine("sideEffect({0}) called", i);
return --i;
}
Конечно, выход есть 2
, когда он должен быть 1
и "sideEffect(i) called"
печатается дважды.
Это что-то делать с фактически 'новый Nullable (--i)' инлайн, потому что если вы назначаете это к переменной *, тогда * выполните операцию, это нормально. Что также странно, если я поставил точку останова на эту строку, а затем положил в watch 'new Nullable (--i)' it уменьшает 'i' (что имеет смысл), но * увеличивает * конечный результат на тот же номер: s –
James
@James: Wierd ... это, похоже, не является желательным поведением ... – InBetween
ну, откуда я стою, я бы сказал нет, или, по крайней мере, не то, что я ожидал бы. Я бы ожидал, что новая «нулевая переменная» будет создана «на лету», которая равна 0. – James