Posted at

Genericの元型を取得する(Class転記)

More than 3 years have passed since last update.

Classから他のClassに値を転記するときに作ったもの。

「decimal?」は「GetProperties」で回して「PropertyType」を参照すると「Nullable」で返ってくるらしく、めちゃくちゃハマった記憶があるw


メソッド

public Type GetTypeEx(Type value)

{
Type result = value;
if (result.IsGenericType)
{
if (result.GetGenericTypeDefinition() == typeof(Nullable<>))
{
// Nullableの場合、元の型を取得
// Nullable<int> → int
result = Nullable.GetUnderlyingType(value);
}
else
{
// System.TypeがGenericの場合、値のSystem.Typeを取得
// List<int> → int
result = result.GetGenericArguments()[0];
}
}
return result;
}


サンプル

public class Hoge

{
private decimal? _piyo = 0;
public decimal? Piyo
{
get { return this._piyo; }
set { this._piyo = value; }
}
}

private void sample()
{
decimal? target1 = 0;
var result1 = this.GetTypeEx(target1.GetType());
// result1 {Name = "Decimal" FullName = "System.Decimal"} System.Type {System.RuntimeType}

var target2 = new List<int>();
var result2 = this.GetTypeEx(target2.GetType());
// result2 {Name = "Int32" FullName = "System.Int32"} System.Type {System.RuntimeType}

var target3 = new List<int?>();
var result3 = this.GetTypeEx(target3.GetType());
result3 = result3.GetTypeEx();
// result3 {Name = "Int32" FullName = "System.Int32"} System.Type {System.RuntimeType}

var target4 = new Hoge();
var result4 = this.GetTypeEx(target4.Piyo.GetType());
// result4 {Name = "Decimal" FullName = "System.Decimal"} System.Type {System.RuntimeType}

System.Reflection.PropertyInfo[] targetProperties = target4.GetType().GetProperties();
foreach (System.Reflection.PropertyInfo target in targetProperties)
{
var p = typeof(Hoge).GetProperty(target.Name);
var result5 = this.GetTypeEx(p.PropertyType);
// result5 {Name = "Decimal" FullName = "System.Decimal"} System.Type {System.RuntimeType}
}
}