これは純粋な好奇心/挑戦であり、実用的な重要性はまったくありません。だから私は仕事を成し遂げる代替ソリューションを探していません.
この質問からDBNullをチェックしてから変数に割り当てる最も効率的な方法は? 次のようなこの回答が見つかりました。
oSomeObject.IntMemeber = oRow["Value"] as int? ?? iDefault;
oSomeObject.StringMember = oRow["Name"] as string ?? sDefault;
上記の式を 1 つのジェネリック関数 (または 2 つ以上) に移動して、int?
andstring
の両方を受け入れ、次のように呼び出すことができますか?
oSomeObject.IntMemeber = oRow.Read<int?>("Value", 0); //iDefault is now 0
//or
oSomeObject.IntMemeber = oRow.Read<int>("Value"); //iDefault is now default(int)
//and
oSomeObject.StringMember = oRow.Read<string>("Name"); //sDefault is now default(string)
要件:
1) DBNull
s の場合、デフォルト値を指定するオプションが必要です。default(T)
デフォルト値を指定しない場合に備えて、返すオプションも必要です。したがって、これは機能しません:
public static T Read<T>(this IDataRecord dr, string field, T defaultValue) where T : class
{
return dr[field] as T ?? defaultValue;
}
public static T? Read<T>(this IDataRecord dr, string field, T? defaultValue) where T : struct
{
return dr[field] as T? ?? defaultValue;
}
電話できないからoSomeObject.StringMemeber = oRow.Read<string>("Name")
オプションのパラメーターである必要はありません。オーバーロードすることもできます。
public static T Read<T>(this IDataRecord dr, string field) where T : class
{
return dr[field] as T ?? default(T);
}
public static T? Read<T>(this IDataRecord dr, string field) where T : struct
{
return dr[field] as T? ?? default(T?);
}
public static T Read<T>(this IDataRecord dr, string field, T defaultValue) where T : class
{
return dr[field] as T ?? defaultValue;
}
public static T? Read<T>(this IDataRecord dr, string field, T? defaultValue) where T : struct
{
return dr[field] as T? ?? defaultValue;
}
メソッド 1 と 2 はまったく同じ署名を持っているため、これはコンパイルされません。
2) ジェネリック関数 (オーバーロードの場合) は同じ名前にする必要があります。
3)as
キーワードは、型のチェックとキャストを使用する必要があります。前に述べたようにIDataRecord
、パフォーマンスなどを読み取ったり、強化したりするためのソリューションを実際に探しているわけではありません。
似たような質問があります
as
しかし、これはキーワードに非常に固有です。したがって、そこにある答えは当てはまりません。
補遺: これに対する解決策は 1 つではありません。どちらが最もエレガントな選択肢であるかを受け入れます。