1. C# ジェネリック (ジェネリック)
ジェネリックを 使用すると、クラスまたはメソッド内のプログラミング要素のデータ型の仕様の記述を、プログラムで実際に使用するまで遅らせることができます。言い換えれば、ジェネリックを使用すると、任意のデータ型で機能するクラスまたはメソッドを作成できます。
データ型の置換パラメーターを使用して、クラスまたはメソッドの仕様を記述できます。コンパイラは、クラスのコンストラクターまたはメソッドへの関数呼び出しを検出すると、指定されたデータ型を処理するコードを生成します。次の簡単な例は、概念を理解するのに役立ちます。
using System;
using System.Collections.Generic;
namespace GenericApplication
{
public class MyGenericArray<T>
{
private T[] array;
public MyGenericArray(int size)
{
array = new T[size + 1];
}
public T getItem(int index)
{
return array[index];
}
public void setItem(int index, T value)
{
array[index] = value;
}
}
class Tester
{
static void Main(string[] args)
{
// 声明一个整型数组
MyGenericArray<int> intArray = new MyGenericArray<int>(5);
// 设置值
for (int c = 0; c < 5; c++)
{
intArray.setItem(c, c*5);
}
// 获取值
for (int c = 0; c < 5; c++)
{
Console.Write(intArray.getItem(c) + " ");
}
Console.WriteLine();
// 声明一个字符数组
MyGenericArray<char> charArray = new MyGenericArray<char>(5);
// 设置值
for (int c = 0; c < 5; c++)
{
charArray.setItem(c, (char)(c+97));
}
// 获取值
for (int c = 0; c < 5; c++)
{
Console.Write(charArray.getItem(c) + " ");
}
Console.WriteLine();
Console.ReadKey();
}
}
}
0 5 10 15 20 アブデ
1.1 一般的な機能
ジェネリックの使用は、特に次の側面でプログラムの機能を強化するための手法です。
- コードの再利用を最大化し、タイプ セーフを保護し、パフォーマンスを向上させるのに役立ちます。
- ジェネリック コレクション クラスを作成できます。.NET Framework クラス ライブラリには、 System.Collections.Generic名前空間 にいくつかの新しいジェネリック コレクション クラスが含まれています。System.Collections のコレクション クラスの代わりに、これらのジェネリック コレクション クラスを使用できます 。
- 独自のジェネリック インターフェイス、ジェネリック クラス、ジェネリック メソッド、ジェネリック イベント、およびジェネリック デリゲートを作成できます。
- ジェネリック クラスを制約して、特定のデータ型のメソッドにアクセスすることができます。
- 汎用データ型で使用される型に関する情報は、リフレクションを使用して実行時に取得できます。
1.2 一般的な方法
上記の例では、ジェネリック クラスを使用しており、型パラメーターを使用してジェネリック メソッドを宣言できます。次のプログラムは、概念を示しています。
using System;
using System.Collections.Generic;
namespace GenericMethodAppl
{
class Program
{
static void Swap<T>(ref T lhs, ref T rhs)
{
T temp;
temp = lhs;
lhs = rhs;
rhs = temp;
}
static void Main(string[] args)
{
int a, b;
char c, d;
a = 10;
b = 20;
c = 'I';
d = 'V';
// 在交换之前显示值
Console.WriteLine("Int values before calling swap:");
Console.WriteLine("a = {0}, b = {1}", a, b);
Console.WriteLine("Char values before calling swap:");
Console.WriteLine("c = {0}, d = {1}", c, d);
// 调用 swap
Swap<int>(ref a, ref b);
Swap<char>(ref c, ref d);
// 在交换之后显示值
Console.WriteLine("Int values after calling swap:");
Console.WriteLine("a = {0}, b = {1}", a, b);
Console.WriteLine("Char values after calling swap:");
Console.WriteLine("c = {0}, d = {1}", c, d);
Console.ReadKey();
}
}
}
swap を呼び出す前の Int 値: a = 10、b = 20 swap を呼び出す前の Char 値: c = I、d = V swap を呼び出した後の Int 値: a = 20、b = 10 swap を呼び出した後の Char 値: c = V、d =私
1.3 一般的な委譲
型パラメーターを使用してジェネリック デリゲートを定義できます。例えば:
delegate T NumberChanger<T>(T n);
using System;
using System.Collections.Generic;
delegate T NumberChanger<T>(T n);
namespace GenericDelegateAppl
{
class TestDelegate
{
static int num = 10;
public static int AddNum(int p)
{
num += p;
return num;
}
public static int MultNum(int q)
{
num *= q;
return num;
}
public static int getNum()
{
return num;
}
static void Main(string[] args)
{
// 创建委托实例
NumberChanger<int> nc1 = new NumberChanger<int>(AddNum);
NumberChanger<int> nc2 = new NumberChanger<int>(MultNum);
// 使用委托对象调用方法
nc1(25);
Console.WriteLine("Value of Num: {0}", getNum());
nc2(5);
Console.WriteLine("Value of Num: {0}", getNum());
Console.ReadKey();
}
}
}
Num の値: 35 Num の値: 175
ジェネリック メソッド/ジェネリック クラスを宣言するとき、特定の条件のいくつかを満たすために、特定の制約をジェネリックに追加できます。
using System;
using System.Web.Caching;
namespace Demo.CacheManager
{
public class CacheHelper<T> where T:new()
{
}
}
一般的な資格:
- T: Struct (型パラメーターは値型でなければなりません。Nullable 以外の任意の値型を指定できます)
- T: クラス (型パラメーターは、任意のクラス、インターフェイス、デリゲート、または配列型を含む参照型である必要があります)
- T: new() (型パラメーターには、パラメーターのないパブリック コンストラクターが必要です。他の制約と共に使用する場合は、new() 制約を最後に指定する必要があります)
- T:<基本クラス名> 型パラメーターは、指定された基本クラスのものであるか、指定された基本クラスから派生したものでなければなりません
- T:<インターフェイス名> 型パラメーターは、指定されたインターフェイスであるか、指定されたインターフェイスを実装する必要があります。複数のインターフェイス制約を指定できます。制約インターフェイスはジェネリックにすることもできます。
- T:う
2.c# 匿名メソッド
デリゲートは、同じラベルを持つメソッドを参照するために使用されます。つまり、デリゲート オブジェクトを使用して、デリゲートが参照できるメソッドを呼び出すことができます。
匿名メソッドは、 コード ブロックをデリゲート パラメーターとして渡すための手法を提供します。匿名メソッドは、名前がなく本体のみを持つメソッドです。
匿名メソッドでは、戻り値の型を指定する必要はありません。メソッド本体内の return ステートメントから推測されます。
2.1 匿名メソッドを記述するための構文
匿名メソッドは、 delegateキーワードを使用して デリゲート インスタンスを作成することによって宣言されます。例えば:
delegate void NumberChanger(int n);
...
NumberChanger nc = delegate(int x)
{
Console.WriteLine("Anonymous Method: {0}", x);
};
コード ブロック Console.WriteLine("Anonymous Method: {0}", x); は匿名メソッドの本体です。
デリゲートは、匿名メソッドまたは名前付きメソッド (つまり、メソッド パラメーターをデリゲート オブジェクトに渡す) を介して呼び出すことができます。
注: 匿名メソッドの本体の後に ; が必要です。
例えば:
nc(10);
using System;
delegate void NumberChanger(int n);
namespace DelegateAppl
{
class TestDelegate
{
static int num = 10;
public static void AddNum(int p)
{
num += p;
Console.WriteLine("Named Method: {0}", num);
}
public static void MultNum(int q)
{
num *= q;
Console.WriteLine("Named Method: {0}", num);
}
static void Main(string[] args)
{
// 使用匿名方法创建委托实例
NumberChanger nc = delegate(int x)
{
Console.WriteLine("Anonymous Method: {0}", x);
};
// 使用匿名方法调用委托
nc(10);
// 使用命名方法实例化委托
nc = new NumberChanger(AddNum);
// 使用命名方法调用委托
nc(5);
// 使用另一个命名方法实例化委托
nc = new NumberChanger(MultNum);
// 使用命名方法调用委托
nc(2);
Console.ReadKey();
}
}
}
匿名メソッド: 10 名前付きメソッド: 15 名前付きメソッド: 30