C# 제네릭(제네릭스)
제네릭(제네릭스)
다양한 유형에 해당하는 함수(또는 클래스)를 정의할 수 있습니다.
예를 들어, 다음과 같은 함수가 있다고 가정합니다.
Int32 score = 5;
Int32 old_score = 3;
public static Int32 GetHighestScore()
{
return (score > old_score) ? score : old_score;
}
만일 score
와 old_score
가 double
이나 float
이었을 경우,
다음과 같이 별도로 함수를 정의해야합니다.
public static Int32 GetHighestScore()
{
return (score > old_score) ? score : old_score;
}
double score = 5;
double old_score = 3;
public static double GetHighestScoreA()
{
return (score > old_score) ? score : old_score;
}
이와 같이, 복수의 패턴을 상정한 함수를 정의하는 것으로 해결합니다.
그러나 이것은 나쁜 예입니다.
하드 코딩이며 프로그램의 유지 보수성 (보수성)도 최악입니다.
이것을 해결해주는 것이 제네릭입니다.
이 경우 다음과 같이 함수 정의를 수행합니다.
static Int32 score = 5;
static Int32 old_score = 3;
public static unsafe T GetHighestScore<T>(T one, T two) where T : unmanaged, IComparable
{
if(one.CompareTo(two) > 0)
{
return one;
}
return two;
}
여기서, where T : unmanaged
는, 형태가 언매니지드형인 것을 조건으로 한다고 하는 의미입니다.
관리되지 않는 유형이란?
sbyte
byte
, short
, int
, uint
, long
,ulong
, char
, float
, double
, decimal
, bool
가 관리되지 않는 유형입니다.
비관리형(C# 참조)
실례
실례로서, Marshal
의 StructureToPtr
를 메소드로서 간이화해 보겠습니다.
(※ Marshal.StructureToPtr()
도 제네릭형으로서 정의되고 있군요!)
public struct myStruct
{
public int x;
public int y;
}
static void Main(string[] args)
{
Console.Title = "ジェネリック";
myStruct ms = new myStruct();
var pStructure = StructureToPointer<myStruct>(ms);
Console.WriteLine("構造体ポインタ: " + (Int32)(pStructure));
Console.ReadKey();
}
////////////////////////////////////////////////////////////////////////
// 構造体のマーシャリング
////////////////////////////////////////////////////////////////////////
public unsafe static IntPtr StructureToPointer<T>(T 構造体) where T : struct
{
var size = Marshal.SizeOf(構造体.GetType());
IntPtr pStructure = Marshal.AllocCoTaskMem(size); //アンマネージドメモリの確保
Marshal.StructureToPtr(構造体, pStructure, false); //確保した領域に構造体ポインタを展開
Marshal.DestroyStructure(pStructure, typeof(T));//後処理
Marshal.FreeCoTaskMem(pStructure);//確保したアンマネージドメモリの解放
return pStructure;
}
구조체에서 구조체 포인터로의 마샬링을 단순화하는 함수입니다.
여기서는, where T : struct
라고 해, 형태가 struct
인 것을 조건으로 합니다.
본래, 매니지드형인 (언매니지드형이 아니다) 제네릭 함수에서는 sizeof()
(을)를 사용할 수 없습니다. ( sizeof()
가 언매니지드형에만 대응하고 있기 때문에)
그래서 Marshal.Sizeof()
를 사용합니다.
실행 결과:
Reference
이 문제에 관하여(C# 제네릭(제네릭스)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/kkent030315/items/4b1f8b3bad8a1cb6307b
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Int32 score = 5;
Int32 old_score = 3;
public static Int32 GetHighestScore()
{
return (score > old_score) ? score : old_score;
}
public static Int32 GetHighestScore()
{
return (score > old_score) ? score : old_score;
}
double score = 5;
double old_score = 3;
public static double GetHighestScoreA()
{
return (score > old_score) ? score : old_score;
}
static Int32 score = 5;
static Int32 old_score = 3;
public static unsafe T GetHighestScore<T>(T one, T two) where T : unmanaged, IComparable
{
if(one.CompareTo(two) > 0)
{
return one;
}
return two;
}
실례로서,
Marshal
의 StructureToPtr
를 메소드로서 간이화해 보겠습니다.(※
Marshal.StructureToPtr()
도 제네릭형으로서 정의되고 있군요!)public struct myStruct
{
public int x;
public int y;
}
static void Main(string[] args)
{
Console.Title = "ジェネリック";
myStruct ms = new myStruct();
var pStructure = StructureToPointer<myStruct>(ms);
Console.WriteLine("構造体ポインタ: " + (Int32)(pStructure));
Console.ReadKey();
}
////////////////////////////////////////////////////////////////////////
// 構造体のマーシャリング
////////////////////////////////////////////////////////////////////////
public unsafe static IntPtr StructureToPointer<T>(T 構造体) where T : struct
{
var size = Marshal.SizeOf(構造体.GetType());
IntPtr pStructure = Marshal.AllocCoTaskMem(size); //アンマネージドメモリの確保
Marshal.StructureToPtr(構造体, pStructure, false); //確保した領域に構造体ポインタを展開
Marshal.DestroyStructure(pStructure, typeof(T));//後処理
Marshal.FreeCoTaskMem(pStructure);//確保したアンマネージドメモリの解放
return pStructure;
}
구조체에서 구조체 포인터로의 마샬링을 단순화하는 함수입니다.
여기서는,
where T : struct
라고 해, 형태가 struct
인 것을 조건으로 합니다.본래, 매니지드형인 (언매니지드형이 아니다) 제네릭 함수에서는
sizeof()
(을)를 사용할 수 없습니다. ( sizeof()
가 언매니지드형에만 대응하고 있기 때문에)그래서
Marshal.Sizeof()
를 사용합니다.실행 결과:
Reference
이 문제에 관하여(C# 제네릭(제네릭스)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/kkent030315/items/4b1f8b3bad8a1cb6307b텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)