Что лучше?приведение обнуляемого типа или получение значения с помощью свойства Value? - PullRequest
26 голосов
/ 19 августа 2011

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

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

Ответы [ 3 ]

38 голосов
/ 19 августа 2011

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

Нет.Они оба компилируются в один и тот же IL.Приведение является синтаксическим сахаром для свойства 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, я могу изменить переменную по мере необходимости.На мой взгляд, жесткое приведение не добавляет ничего с точки зрения читабельности, но оно стоит с точки зрения удобства обслуживания.

9 голосов
/ 19 августа 2011

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

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

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

Читабельность?


// 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;
}
4 голосов
/ 27 ноября 2014

(Старый вопрос? Кому интересно. Современная проблема.)

Во-первых, Джо дает отличный ответ , и, учитывая текущее состояние C #, я думаю,Я согласен с ним:

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

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

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

...