В чем преимущества замены (int)reader[0] на reader.GetInt32(0)? Я уверен, что такие функции приведения существуют по какой-то причине, но, кроме того, что мне кажется более эстетичным избегать использования приведения себя, я не уверен, каковы эти причины.
@nawal: Необязательно, поскольку MS разделяет исходный код. И источник между ними довольно разный, но в настоящее время у меня нет времени выяснять, почему.





Первый также может принимать имя столбца как строку, а не индекс, и будет пытаться преобразовать значение столбца в int. Последний принимает только индекс, и преобразование не выполняется.
В коде ....
void OneWay()
{
System.Data.SqlClient.SqlDataReader reader = null;
int i = reader.GetInt32(0);
}
void OtherWay()
{
System.Data.SqlClient.SqlDataReader reader = null;
int i = (int)reader[0];
}
В Иллинойсе
.method private hidebysig instance void OneWay() cil managed
{
.maxstack 2
.locals init (
[0] class [System.Data]System.Data.SqlClient.SqlDataReader reader,
[1] int32 i)
L_0000: nop
L_0001: ldnull
L_0002: stloc.0
L_0003: ldloc.0
L_0004: ldc.i4.0
L_0005: callvirt instance int32 [System.Data]System.Data.Common.DbDataReader::GetInt32(int32)
L_000a: stloc.1
L_000b: ret
}
.method private hidebysig instance void OtherWay() cil managed
{
.maxstack 2
.locals init (
[0] class [System.Data]System.Data.SqlClient.SqlDataReader reader,
[1] int32 i)
L_0000: nop
L_0001: ldnull
L_0002: stloc.0
L_0003: ldloc.0
L_0004: ldc.i4.0
L_0005: callvirt instance object [System.Data]System.Data.Common.DbDataReader::get_Item(int32)
L_000a: unbox.any int32
L_000f: stloc.1
L_0010: ret
}
Итак, ИЖ разные, но я сомневаюсь, что между ними есть какая-то заметная разница. Может быть, после миллиона итераций вы заметите разницу, но вряд ли.
Мне запомнился unbox.any, но вы, наверное, правы: upvote.
О: Мне также интересно узнать о результат кода, если в запросе, скажем, было двойное значение в этом столбце, а не int.
unbox, вероятно, является причиной того, что синтаксис reader [0] возвращает упакованное целое число (как объект), и это, я думаю, суть проблемы ... в «одностороннем» вызове DbDataReader :: GetInt32 () возвращает Int32, а так бокса / распаковки не происходит ... Спасибо!
Вероятно, стоило бы получить IL методов SqlDataReader.GetInt32 и get_Item (int32), чтобы узнать, в чем разница. Я полагаю, что в том или ином месте должен проходить кастинг.
reader [0] возвращает System.Object, (int) reader [0] фактически выполняет приведение из Object в Int32.
Если вы вызываете методы GetXXX (0), преобразования не выполняются. Следовательно, данные, полученные из потока, уже должны быть того типа, который указан в методе.
Если тип полученных данных не совпадает или столбец имеет DBNull, он генерирует исключение InvalidCastException.
не могли бы вы отразить исходный код функций reader.Get (index)? Я не думаю, что они делают приведение, вместо этого внутри себя Convert.ToInt32. В прошлом у меня были проблемы с кастингом, хотя он может быть немного быстрее. См. Этот вопрос тоже. DBNulls может вызвать проблемы, поэтому не используйте его в основном.