2017-12-06 61 views
0

出力がDBNullであるかどうかをチェックし、ジェネリック型がnullの場合はnullを返す関数を記述しています。そうでなければ、単にエラーをスローします。ジェネリック型がnullableの場合はnullを返します

アップデート:私はdefault(T)リターンがすべてのNULL可能フィールドにNULLかどうかわからないのですが、すべての推奨

public T Get<T>(string key) 
{ 
    int ordinal = reader.GetOrdinal(key); 
    if (reader.IsDBNull(ordinal)) 
    { 
     if (typeof(T).GetTypeInfo().IsValueType && Nullable.GetUnderlyingType(typeof(T)) == null) // isn't a nullable field 
      throw new InvalidCastException(); 
     else return default(T); 
    } 
    return reader.GetFieldValue<T>(ordinal); 
} 

を追加しました。今はnullを返すように他の方法がある場合は?

+2

'reader.GetFieldType(key)'が通常 'DBNull'を返すかどうかはわかりません - それでも動作しますか?もしもnullでないなら、カラムが保持するものを表す何かを返すことを期待しています* –

+0

提案(Marcの答え/コメントに加えて)のように、 'if'ステートメントを逆転させます* null、 'return ...;')、そして 'else ...'を' throw ...; 'のために除外します。 –

答えて

5

はい、default(T)はあなたが正常に動作する必要があります持っているので、何を、実際にSomeType?/Nullable<SomeType>あるすべてのTためnull様価値の正しい種類です。

あなたはしかしstringbyte[]のようなものを検討する必要があります - これらはのデータベースから来ることができるし、nullにすることができます。

値が<decimal>の場合、誰かが単に間違いを犯したときに何をするべきかを考えて、<int>を求めることもできます。その場合、InvalidCastExceptionが発生します。例外を使用するよりも適切かもしれないIDataReaderIsDBNull()メソッドがあります。最後に

:例外をキャッチして処理する、コンピュータリソースの面ではthrow;throw e;

+1

[" throw "と" throw ex "の違いはありますか?](https ://stackoverflow.com/a/730255/209259)。 –

+0

@ShaiCohen私は私のコメントでその質問にマークの答えをリンクしました。それは私のOPではなかった:) –

2

を好むが、非常に高価な作業です。あなたのメソッドは、ロジックフローの一部として例外を使用しています。これは、あなたが解決したい問題を見て間違った方法です。

また、特にInvalidCastException例外をキャッチしています。この例外は、null参照をキャストしようとする以外の場合に発生する可能性があります。潜在的に有効なエラーを隠しているか誤解しています。あなたに何時間もの不満を抱かせて、髪を引っ張るようなデバッグが必要なものです。

以下は元の方法と同じ動作をしますが、統合エラー処理中にスタックを巻き戻すオーバーヘッドはありません。

public T Get<T>(string key) 
{ 
    if(reader.IsDbNull(reader.GetOrdinal(key))) 
    { 
     //IF YOU SPECIFICALLY WANT TO THROW AN ERROR IF A VALUE TYPE 
     //if (typeof(T).IsValueType) 
     //{ throw new InvalidCastException(); } 
     return default(T); 
    } 

    return reader.GetFieldValue<T>(reader.GetOrdinal(key)); 
} 
関連する問題