Quantcast
Channel: C#タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9707

[C#]struct制約のないジェネリック型の値から、Nullable.Value(またはHasValue)にアクセスする

$
0
0

ジェネリック型を使用し、struct制約があればこんなコードですが、

voidFunc<T>(T?val)whereT:struct{Console.WriteLine(val.Value.GetHashCode());}long?value=long.MaxValue;Func(value);

これを制約なしでアクセスしたいわけです。

voidFunc<T>(Tval){Console.WriteLine(val.Value.GetHashCode());^^^^^//アクセスできない}long?value=long.MaxValue;Func(value);

実行時にNullable.GetUnderlyingType(typeof(T));System.Typeを取得してリフレクションでも取得できますが、もう少し効率の良さそうな方法を取りたいので、Expression式を使います。

Expression式を使用したサンプルコード

usingSystem;usingstaticSystem.Linq.Expressions.Expression;staticclassInnerValueHashCode{publicstaticintGet<T>(Tvalue)=>Impl<T>.Delegate(value);privatestaticclassImpl<T>{publicstaticFunc<T,int>GenerateFunc(){varnullableValue=Parameter(typeof(T),"nullableValue");varunderlyingType=Nullable.GetUnderlyingType(typeof(T));varcallExpression=Call(Property(nullableValue,typeof(T),"Value"),underlyingType.GetMethod("GetHashCode",Type.EmptyTypes));varlambda=Lambda<Func<T,int>>(callExpression,nullableValue);returnlambda.Compile();}internalreadonlystaticFunc<T,int>Delegate=GenerateFunc();}}long?value=long.MaxValue;InnerValueHashCode.Get(value);

もちろん Nullable<T>以外を渡すと正しく動作しないので、事前にジェネリック型のチェックは必要です。


Viewing all articles
Browse latest Browse all 9707

Trending Articles