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

C# ジェネリック(ジェネリクス)

$
0
0

ジェネリック(ジェネリクス)

様々な型に対応する関数(やクラス)を定義することができます。

例えば、以下の様な関数があったとします。

Int32score=5;Int32old_score=3;publicstaticInt32GetHighestScore(){return(score>old_score)?score:old_score;}

万が一、scoreold_scoredoublefloatであった場合、
以下の様に別で関数定義する必要があります。

publicstaticInt32GetHighestScore(){return(score>old_score)?score:old_score;}doublescore=5;doubleold_score=3;publicstaticdoubleGetHighestScoreA(){return(score>old_score)?score:old_score;}

といったように、複数のパターンを想定した関数を定義することで解決します。
しかしながら、これは悪い例です。
ハードコーディングですし、プログラムのメンテナンス性(保守性)も最悪です。
これを解決してくれるのが、ジェネリックです。

今回の場合、以下の様に関数定義を行います。

staticInt32score=5;staticInt32old_score=3;publicstaticunsafeTGetHighestScore<T>(Tone,Ttwo)whereT:unmanaged,IComparable{if(one.CompareTo(two)>0){returnone;}returntwo;}

ここでいう、where T : unmanagedは、型がアンマネージド型であることを条件にするという意味です。

アンマネージド型とは

sbytebyteshortintuintlong
ulongcharfloatdoubledecimalbool
がアンマネージド型です。
アンマネージド型 (C# リファレンス)

実例

実例として、MarshalStructureToPtrをメソッドとして簡易化してみます。
(※Marshal.StructureToPtr()もジェネリック型として定義されていますね!)

publicstructmyStruct{publicintx;publicinty;}staticvoidMain(string[]args){Console.Title="ジェネリック";myStructms=newmyStruct();varpStructure=StructureToPointer<myStruct>(ms);Console.WriteLine("構造体ポインタ: "+(Int32)(pStructure));Console.ReadKey();}////////////////////////////////////////////////////////////////////////// 構造体のマーシャリング////////////////////////////////////////////////////////////////////////publicunsafestaticIntPtrStructureToPointer<T>(T構造体)whereT:struct{varsize=Marshal.SizeOf(構造体.GetType());IntPtrpStructure=Marshal.AllocCoTaskMem(size);//アンマネージドメモリの確保Marshal.StructureToPtr(構造体,pStructure,false);//確保した領域に構造体ポインタを展開Marshal.DestroyStructure(pStructure,typeof(T));//後処理Marshal.FreeCoTaskMem(pStructure);//確保したアンマネージドメモリの解放returnpStructure;}

構造体から構造体ポインタへのマーシャリングを簡易化する関数です。
ここでは、where T : structとし、型がstructであることを条件とします。

本来、マネージド型である(アンマネージド型ではない)ジェネリック関数ではsizeof()を使用することができません。(sizeof()がアンマネージド型にのみ対応している為)
なので、Marshal.Sizeof()を使用します。

実行結果:
e94d408e6c8952113f74b4c19bdb3cb7.png


Viewing all articles
Browse latest Browse all 9699

Trending Articles