検索

この章は非常に長いため、いくつかの部分に分ける必要があるかもしれません:)

20.ジェネリック

20.1 ジェネリック クラス宣言

ジェネリック クラス宣言は、実際の型を形成するために型パラメーターを指定する必要があるクラスの宣言です。



クラス宣言では、オプションで型パラメータを定義できます。

class-declaration: (クラス宣言)
attributesopt class-modifiersopt class identifieropt type-parameter-listopt class –baseopt type-parameter-constraints-clauseopt class-body;opt (属性 オプションのクラス修飾子 オプションのクラス識別子 can オプションの型パラメーター リストオプションの基本クラス オプションの型パラメーター制約ステートメント オプションのクラス本体; オプション)
型パラメーターのリストが提供されない限り、クラス宣言で型パラメーター化された制約ステートメントを提供する必要はありません。

型パラメーターのリストを提供するクラス宣言は、ジェネリック クラス宣言です。さらに、ジェネリック クラス宣言またはジェネリック構造体宣言に埋め込まれたクラスは、それ自体がジェネリック クラス宣言です。構築型を作成するには、包含型の型パラメータが提供される必要があるためです。

ジェネリック クラスは構築型 (§20.5) を使用して渡されます。 )。ジェネリック クラス宣言

class List{}
ここでは、構築された型 List、List、List> の例をいくつか示します。構築型は 1 つ以上のパラメータを取ることができます。たとえば、List はオープン構築型と呼ばれます。 List など、型パラメーターを使用しない構築型は、閉じた構築型と呼ばれます。

ジェネリック型は「オーバーロード」できません。つまり、通常の型と同様に、ジェネリック型はスコープ内で一意の名前を付ける必要があります。


class C{}
class C{}//エラー、C が 2 回定義されています
class C{}//エラー、C が 2 回定義されています
ただし、修飾されていない型名ではルックアップ (§20.9.3) およびメンバー アクセス (§20.9.4) で使用される型ルックアップ ルールでは、型パラメーターの数が考慮されます。

20.1.1 型パラメータ

型パラメータはクラス宣言で指定できます。各型パラメーターは、構築型の作成に使用される型パラメーターのプレースホルダーを示す単純な識別子です。型パラメーターは、後で提供される型の正式なプレースホルダーです。対照的に、型パラメータ §20.5.1) は、構築された型が参照されるときの実際の型の単なるプロキシです。

type-parameter-list: (型パラメータリスト:)
parameters type-parameter (型パラメータ、型パラメータ)
type-parameter: (型パラメータ:)
attributesopt identifier (属性のオプションの識別子)

クラス宣言内の各型パラメータは、クラスの宣言空間 (§3.3 ) にあり、名前を定義します。したがって、クラスで宣言された別の型パラメーターまたはメンバーと同じ名前を持つことはできません。型パラメータに型自体と同じ名前を付けることはできません。

クラス内の型パラメーターのスコープ (§3.7)。基底クラス、型パラメーター制約ステートメント、クラス本体が含まれます。クラスのメンバーとは異なり、派生クラスには拡張されません。そのスコープ内では、型パラメーターを型として使用できます。

type (型):

value-type (値型)
reference-type (参照型)
type-parameter (型パラメータ)
型パラメータはさまざまな実際の型引数によってインスタンス化できるため、型パラメータには他のタイプとは操作や制限が若干異なります。以下のものが含まれます。

型パラメーターを使用して、基本型またはインターフェイスを直接宣言することはできません。
型パラメーターのメンバー検索ルールについては、制約が存在する場合、型パラメーターに適用される制約に依存します。詳細については、§20.7.4 を参照してください。



型パラメーターに可能な変換は、型パラメーターに適用される制約 (存在する場合) によって異なります。詳細については、§20.7.4 を参照してください。
型パラメータがクラス制約 (§20.7.4) によって制約されていない限り、リテラル null は型パラメータで指定された型に変換できません。ただし、代わりにデフォルト値式 (§20.8.1) を使用することもできます。さらに、型パラメータで指定された型の値は、「==」および「!=」を使用して null と比較される場合があります (§20.8.4)。
型パラメーターがコンストラクター制約 (§20.7) によって制約されている場合、新しい式は 1 つの型パラメーターでのみ使用できます。
型パラメータは属性内のどこでも使用できません。
型パラメータはメンバー アクセスに使用したり、静的メンバーや入れ子になった型の型名を表すことはできません (§20.9.1、§20.9.4)。
安全でないコードでは、型パラメータをマネージド型として使用することはできません (§18.2)。

型として、型パラメーターは純粋にコンパイル時の構造です。実行時、各型パラメーターは、ジェネリック型宣言で提供される型引数によって指定される実行時型にバインドされます。このため、実行時には、型パラメータで宣言された変数の型は閉じた型になります (§20.5.2)。実行時に実行されるすべてのステートメントと式は、そのパラメーターによって型引数として提供される実際の型の型パラメーターを使用します。



20.1.2 インスタンス型

すべてのクラス宣言には、それに関連付けられた構築型、つまりインスタンス型があります。ジェネリック クラス宣言の場合、インスタンス型は型宣言から構築型 (§20.4) を作成することによって形成され、型パラメーターに対応する各型引数が使用されます。インスタンス化された型は型パラメーターを使用するため、型パラメーターのスコープ内 (クラス宣言内) でのみ有効です。インスタンスの型は、クラス宣言内の this の型です。非ジェネリック クラスの場合、インスタンス型は単なる宣言された型です。以下に、宣言されたいくつかのクラスとそのインスタンス タイプを示します。

class A<T> //实例类型:A<T>
{
class B{} //实例类型:A<T>.B
class C<U>{} //实例类型:A<T>.C<U>
}
class D{} //实例类型:D

20.1.3 基本クラスの仕様

クラス宣言で指定された基本クラスは構築型である可能性があります (§20.5)。基本クラス自体を型パラメーターにすることはできませんが、そのスコープ内に型パラメーターを含めることはできます。

class Extend: V{}//エラー、型パラメータが基底クラスとして使用されています
ジェネリック クラス宣言では System.Attribute を直接または間接基底クラスとして使用できません。

クラス宣言で指定される基本インターフェースは、構築されたインターフェース型にすることができます (§20.5)。基本インターフェイス自体を型パラメーターにすることはできませんが、そのスコープ内に型パラメーターを含めることはできます。次のコードは、構築された型を実装および拡張する方法を示しています。


class C<U,V>{}
Interface I1<V>{}
class D:C<string , int>,I1<string>{}
class E<T>:C<int,T> ,I1<T>{}

ジェネリック型によって宣言された基本インターフェイスは、§20.3.1 で説明されている一意性の規則を満たさなければなりません。

基本クラスまたはインターフェースのメソッドをオーバーライドまたは実装するクラスのメソッドは、特定の型に適切なメソッドを提供する必要があります。以下のコードは、メソッドをオーバーライドして実装する方法を示しています。これについては、§20.1.10 で詳しく説明します。



class C<U,V>
{
public virtual void M1(U x , List<V> y){…}
}
interface I1<V>
{
V M2(V x);
}
class D:C<string , int>,I1<string>
{
public override void M1(string x , List<int> y){…}
public string M2(string x){…}
}

20.1.4 ジェネリッククラスのメンバー

泛型类的所有成员都可以直接地或者作为构造类型的一部分,从任何封闭类(enclosing class)中使用类型参数。当特定的封闭构造类型在运行时被使用时,类型参数的每次使用都由构造类型所提供的实际类型实参所代替。例如


class C<V>
{ 
public V f1; 
public C<V> f2=null;
public C(V x){
this.f1 = x;
this.f2 = this;
}
}
class Application
{
static void Main(){
C<int> x1= new C<int >(1);
Console.WriteLine(x1.f1); //打印1
C<double> x2 = new C<double>(3.1415);
Console.WriteLine(x2.f1); //打印 3.1415
}
}

在实例函数成员之内,this的类型就是声明的实例类型(§20.1.2)。

除了使用类型参数作为类型和成员,在泛型类声明中也遵循和非泛型类成员相同的规则。适用于特定种类成员的附加规则将在后面几节进行讨论。

20.1.5泛型类中的静态字段

在一个泛型类声明中的静态变量,在相同封闭构造类型(§20.5.2)所有实例中被共享,但在不同封闭构造类型的实例中[1],是不被共享的。这些规则不管静态变量的类型包含那种类型参数都适用。

例如

class C<V>
{
static int count = 0;
public C()
{
count++;
}
public static int Count{
get{return count;}
}
}
class Application
{
static void Main()
{
C<int> x1 = new C<int>();
Console.WriteLine(C<int>.Count);//打印 1
C<double> x2 = new C<double>();
Console.WriteLine(C<int>.Count);//打印 1
C<int> x3 = new C<int>();
Console.WriteLine(C<int>.Count);//打印 2
}
}

[1] 这是很容易理解的,因为在运行时,不同的封闭构造类型,是属于不同的类型,比如List 和List 这二者的实例是不能共享静态变量的。

以上就是C#2.0 Specification(泛型一)的内容,更多相关内容请关注PHP中文网(www.php.cn)!


声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
Web、デスクトップ、モバイル開発用のC#.NETWeb、デスクトップ、モバイル開発用のC#.NETApr 25, 2025 am 12:01 AM

C#と.NETは、Web、デスクトップ、モバイル開発に適しています。 1)Web開発では、ASP.Netcoreがクロスプラットフォーム開発をサポートしています。 2)デスクトップ開発では、さまざまなニーズに適したWPFとWINFORMSを使用します。 3)モバイル開発は、Xamarinを介したクロスプラットフォームアプリケーションを実現します。

C#.NETエコシステム:フレームワーク、ライブラリ、およびツールC#.NETエコシステム:フレームワーク、ライブラリ、およびツールApr 24, 2025 am 12:02 AM

C#.NETエコシステムは、開発者がアプリケーションを効率的に構築できるようにするための豊富なフレームワークとライブラリを提供します。 1.ASP.NETCOREは、高性能Webアプリケーションの構築に使用されます。2.EntityFrameWorkCoreは、データベース操作に使用されます。これらのツールの使用とベストプラクティスを理解することにより、開発者はアプリケーションの品質とパフォーマンスを向上させることができます。

azure/awsへのc#.netアプリケーションの展開:ステップバイステップガイドazure/awsへのc#.netアプリケーションの展開:ステップバイステップガイドApr 23, 2025 am 12:06 AM

c#.netアプリをAzureまたはAWSに展開する方法は?答えは、AzureAppServiceとAwselasticBeanStalkを使用することです。 1。Azureでは、AzureAppServiceとAzurePipelinesを使用して展開を自動化します。 2。AWSでは、Amazon ElasticBeanstalkとAwslambdaを使用して、展開とサーバーレス計算を実装します。

C#.NET:強力なプログラミング言語の紹介C#.NET:強力なプログラミング言語の紹介Apr 22, 2025 am 12:04 AM

C#と.NETの組み合わせにより、開発者に強力なプログラミング環境を提供します。 1)C#は、多型と非同期プログラミングをサポートします。2).NETは、クロスプラットフォーム機能と同時処理メカニズムを提供し、デスクトップ、Web、モバイルアプリケーション開発で広く使用されています。

.NETフレームワーク対C#:用語のデコード.NETフレームワーク対C#:用語のデコードApr 21, 2025 am 12:05 AM

.NetFrameworkはソフトウェアフレームワークであり、C#はプログラミング言語です。 1..netframeworkは、デスクトップ、Web、モバイルアプリケーションの開発をサポートするライブラリとサービスを提供します。 2.C#は.NetFrameWork用に設計されており、最新のプログラミング機能をサポートしています。 3..NetFrameworkはCLRを介してコード実行を管理し、C#コードはILにコンパイルされ、CLRによって実行されます。 4. .NetFrameWorkを使用してアプリケーションをすばやく開発し、C#はLINQなどの高度な関数を提供します。 5.一般的なエラーには、タイプ変換と非同期プログラミングデッドロックが含まれます。 VisualStudioツールは、デバッグに必要です。

C#.NETの分解:初心者の概要C#.NETの分解:初心者の概要Apr 20, 2025 am 12:11 AM

C#は、Microsoftが開発した最新のオブジェクト指向プログラミング言語であり、.NETはMicrosoftが提供する開発フレームワークです。 C#は、CのパフォーマンスとJavaのシンプルさを組み合わせており、さまざまなアプリケーションの構築に適しています。 .NETフレームワークは、複数の言語をサポートし、ガベージコレクションメカニズムを提供し、メモリ管理を簡素化します。

C#と.NETランタイム:それらがどのように連携するかC#と.NETランタイム:それらがどのように連携するかApr 19, 2025 am 12:04 AM

C#と.NETランタイムは密接に連携して、開発者に効率的で強力なプラットフォームの開発機能に力を与えます。 1)C#は、.NETフレームワークとシームレスに統合するように設計されたタイプセーフおよびオブジェクト指向のプログラミング言語です。 2).NETランタイムは、C#コードの実行を管理し、ガベージコレクション、タイプの安全性、その他のサービスを提供し、効率的でクロスプラットフォームの操作を保証します。

C#.NET開発:始めるための初心者向けガイドC#.NET開発:始めるための初心者向けガイドApr 18, 2025 am 12:17 AM

C#.NET開発を開始するには、次のことが必要です。1。C#の基本的な知識と.NETフレームワークのコア概念を理解する。 2。変数、データ型、制御構造、関数、クラスの基本概念をマスターします。 3。LINQや非同期プログラミングなど、C#の高度な機能を学習します。 4.一般的なエラーのためのデバッグテクニックとパフォーマンス最適化方法に精通してください。これらの手順を使用すると、C#.NETの世界に徐々に浸透し、効率的なアプリケーションを書き込むことができます。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強力な PHP 統合開発環境

SublimeText3 英語版

SublimeText3 英語版

推奨: Win バージョン、コードプロンプトをサポート!

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

WebStorm Mac版

WebStorm Mac版

便利なJavaScript開発ツール