Подтвердить что ты не робот

Что лучше? лить тип NULL или получить значение со значением Value?

Есть ли преимущество в производительности для одного пути над другим?

Существуют ли другие причины для выбора одного из них?

4b9b3361

Ответ 1

Есть ли преимущество в производительности для одного пути над другим?

Нет. Они оба скомпилируются с тем же ИЛ. Литой является синтаксический сахар для свойства Value. Этот код:

int? x = null;
Console.WriteLine(x.Value);
Console.WriteLine((int)x);

компилируется в эти инструкции IL, игнорируя nop s: (вы можете проверить это самостоятельно, используя ildasm, ILSpy, DotPeek и т.д.)

// int? x = null;
ldloca.s 0
initobj valuetype [mscorlib]System.Nullable`1<int32>

// Console.WriteLine(x.Value);
ldloca.s 0
call instance !!0 [mscorlib]System.Nullable`1<int32>::get_Value()
call void [mscorlib]System.Console::WriteLine(int32)

// Console.WriteLine((int)x);
ldloca.s 0
call instance !!0 [mscorlib]System.Nullable`1<int32>::get_Value()
call void [mscorlib]System.Console::WriteLine(int32)

Существуют ли другие причины для выбора одного из них?

Я предпочитаю избегать кастингов, когда могу, потому что всегда есть возможность выйти из синхронизации с фактическим типом. Если я изменю свою переменную от int? до byte?, то все мои приведения ошибочны, но если я использую .Value, я могу свободно изменять переменную по мере необходимости. Для меня жесткий листок не добавляет ничего с точки зрения удобочитаемости, но он стоит с точки зрения ремонтопригодности.

Ответ 2

Есть ли преимущество в производительности для одного пути над другим?

Производительность будет незначительной

Существуют ли другие причины для выбора одного из них?

читаемость?


// most readable
public int GetValue(int? value)
{
    return value.GetValueOrDefault();
}

// less readable
public int GetValue(int? value)
{
    return value ?? default(int);
}

// least readable
public int GetValue(int? value)
{
    return value.HasValue ? value.Value : default(int);
}

//least readable reversed return type/param type
public int? GetValue(int value)
{
    return value == 0 ? null : (int?)value;
}

Ответ 3

(Старый вопрос: кто заботится. Современная проблема.)

Во-первых, Joe дает отличный ответ, и учитывая текущее состояние С#, я согласен с ним:

... потенциал для их выхода из синхронизации с фактическим типом. Если я изменить мою переменную из int? в байт?, тогда все мои броски ошибочны - но если бы я использовал. Значение, я могу изменить переменную как необходимо.

Проблема заключается в том, что вы всегда выполняете тип, потому что если вы используете .Value, тогда вы совершаете Nullable<TAny>, и если вы используете бросок, вы совершаете "ICastableTo<TSpecific>" составленное имя

Тем не менее, совет Joe по-прежнему действителен, потому что компилятор будет намного лучше использовать недопустимое использование .Value, чем потенциально семантически недействительные приведения, которые все еще могут компилироваться, и вы хотите, чтобы компилятор поймал как можно больше вещей, меняющихся типов.