データベースからさまざまなデータを取得し、それを使用して要求された型のオブジェクトを構築することになっている、驚くほど醜いメソッドがあります。目標は、このメソッドを含むクラスから派生するクラスが比較的クリーンになるように、さまざまな醜さを 1 つの場所にまとめることです。
タイプがnull可能であっても、単一のオブジェクトを返すことになっている場合に問題はありません。
protected T getValue<T>(ParameterObject myParameterObject)
{
var typeOfT = typeof (T);
if (typeOfT == typeof(bool))
{
string val = this.getValue(myParameterObject);
if (val == null)
return default(T);
bool rVal;
if (!Boolean.TryParse(val, out rVal))
return default(T);
return changeType<T>(rVal);
}
if (typeOfT == typeof (double?))
{
string val = this.getValue(myParameterObject);
if (val == null)
return default(T);
double rVal;
if (!Double.TryParse(val, out rVal))
return default(T);
return changeType<T>(rVal);
}
[...]
}
public static T changeType<T>(object value)
{
var t = typeof(T);
if (!t.IsGenericType || t.GetGenericTypeDefinition() != typeof(Nullable<>))
return (T)Convert.ChangeType(value, t);
if (value == null)
return default(T);
t = Nullable.GetUnderlyingType(t);
return (T)Convert.ChangeType(value, t);
}
残念ながら、目的の戻り値の型が IList で、List を返したい場合があります。
protected T getValue<T>(ParameterObject myParameterObject)
{
var typeOfT = typeof (T);
if (typeOfT.IsGenericType)
{
if (typeOfT.GetGenericTypeDefinition() == typeof (IList<>))
{
var genericArgumentType = typeOfT.GenericTypeArguments.FirstOrDefault();
var baseType = typeof (List<>);
var genericType = baseType.MakeGenericType(new[] {genericArgumentType});
var rVal = Activator.CreateInstance(genericType);
[code to populate the list]
return changeType<T>(rVal);
}
[...]
}
T のインスタンスではなくオブジェクトであるため、rVal を返すことはできません。しかし、私の changeType() 関数は失敗し、エラーが発生します。
System.InvalidCastException: オブジェクトは IConvertible を実装する必要があります。
したがって、戻り値の型が IList であるジェネリック メソッドがあり、List であるオブジェクトがありますが、それへの参照は Object 型です。関数から返すことができるようにキャストするにはどうすればよいですか?