検索

21.7 デリゲート インスタンスの等価性

以下のルールは、等価演算子 (§7.9.8) および匿名メソッド デリゲート インスタンスの object.Equals メソッドによって生成される結果に適用されます。
l デリゲート インスタンスが、キャプチャされた外部変数の同じセットを使用して、意味的に同一の匿名メソッド式を評価した結果として得られる場合、それらは等しい (ただし、等しい必要はない) と言われます。
l デリゲート インスタンスが、異なるセマンティクスを持つ匿名メソッド式、またはキャプチャされた外部変数の異なるセットで表される場合、それらは決して等しくありません。

21.8 明示的な割り当て

匿名メソッドのパラメータの明示的な割り当てステータスは、名前付きメソッドの明示的な割り当てステータスと同じです。つまり、参照パラメータと値パラメータには明示的に初期値が割り当てられますが、出力パラメータには初期値を割り当てる必要はありません。また、匿名メソッドが正常に戻る前に、出力パラメータを明示的に割り当てる必要があります (§5.1.6)。
匿名メソッド式のプログラムブロックに制御が移った場合、外部変数vの明示的な代入状態は、無名メソッド式前のvの明示的な代入状態と同じになります。つまり、外部変数への明示的な代入は、匿名メソッド式コンテキストから継承されます。匿名メソッド ブロック内では、明示的な代入は通常のブロック内と同様に推定されます (§5.3.3)。
匿名メソッド式の後の変数 v の明示的な代入状態は、匿名メソッド式の前の明示的な代入状態と同じです。

たとえば、

delegate bool Filter(int i);
void F() {
int max;
// 错误,max没有明确赋值
Filter f = delegate(int n) { return n < max; }
max = 5;
DoWork(f);
}

は、匿名メソッドが宣言されている場所にmaxが明示的に割り当てられていないため、コンパイル時エラーを生成します。例

delegate void D();
void F() {
int n;
D d = delegate { n = 1; };
d();
//错误,n没有明确赋值
Console.WriteLine(n);
}

もコンパイル時エラーを生成します。これは、匿名メソッド内の n の代入は、匿名メソッド外の n の明示的な代入状態に影響を与えないためです。

21.9 メソッド グループの変換

§21.3 で説明した暗黙的な匿名メソッド変換と同様に、メソッド グループ (§7.1) から互換性のあるデリゲート型への暗黙的な変換もあります。
特定のメソッド グループ E とデリゲート型 D について、new D(E) 形式のデリゲート作成式が許可されている場合 (§7.5.10.3 および §20.9.6)、E から D への暗黙的な変換が行われます。変換の結果は、新しい D(E) とまったく同じになります。
次の例

using System;
using System.Windows.Forms;
class AlertDialog
{
Label message = new Label();
Button okButton = new Button();
Button cancelButton = new Button();`
public AlertDialog() {
okButton.Click += new EventHandler(OkClick);
cancelButton.Click += new EventHandler(CancelClick);
...
}
void OkClick(object sender, EventArgs e) {
...
}
void CancelClick(object sender, EventArgs e) {
...
}
}

では、コンストラクターは new を使用して 2 つのデリゲート インスタンスを作成します。暗黙的なメソッド グループ変換を使用すると、これを

public AlertDialog() {
okButton.Click += OkClick;
cancelButton.Click += CancelClick;
...
}

に簡素化できます。他のすべての暗黙的変換および明示的変換と同様に、変換演算子を使用して特定の変換を明示的に実行できます。これを行うには、代わりに例

object obj = new EventHandler(myDialog.OkClick);

を次のように記述できます。

object obj = (EventHandler)myDialog.OkClick;

メソッド合成の匿名メソッド式はオーバーロードの解決に影響を与える可能性がありますが、型推論には関与しません。詳細については、§20.6.4 を参照してください。

21.10 実装例

このセクションでは、標準 C# コンポーネントの形式での匿名メソッドの可能な実装について説明します。ここで説明する実装は、Microsoft C# コンパイラで採用されているのと同じ原則に基づいていますが、これは決して必須ではなく、また唯一可能な実装でもありません。
このセクションの後半でいくつかのサンプル コードを示します。これらには、異なる特性を持つ匿名メソッドが含まれています。各例では、独自の標準 C# 構造を使用したコードの対応する変換を提供します。これらの例では、識別子 D は次のデリゲート型を表すと想定されています。

public delegate void D();

匿名メソッドの最も単純な形式は、外部変数をキャプチャしないものです。

class Test
{
static void F() {
D d = delegate { Console.WriteLine("test"); };
}
}

このコードは、コンパイラによって生成された静的メソッドを参照するデリゲート インスタンスに変換でき、匿名メソッドのコードは静的メソッドに配置されます。 ,

class Test
{
static void F() {
D d = new D(__Method1);
}
static void __Method1() {
Console.WriteLine("test");
}
}

以下の例では、匿名メソッドは this のインスタンス メンバーを参照しています。

class Test
{
int x;
void F() {
D d = delegate { Console.WriteLine(x); };
}
}

これは、匿名メソッド コードを含むコンパイラによって生成されたインスタンス メソッドに変換できます。

class Test
{
int x;
void F() {
D d = new D(__Method1);
}
void __Method1() {
Console.WriteLine(x);
}
}

この例では、匿名メソッドがローカル変数をキャプチャします。


class Test
{
void F() {
int y = 123;
D d = delegate { Console.WriteLine(y); };
}
}

该局部变量的生存期现在至少必须延长到匿名方法委托的生存期为止。这可以通过将局部变量“提升(lifting)”为编译器生成的(compiler-generated)类的字段来完成。局部变量的实例化对应于创建一个编译器生成的类的实例,而访问局部变量将对应于访问编译器生成的类实例的一个字段。并且,匿名方法将成为编译器生成类的实例方法。

class Test
{
void F() {
__locals1 = new __Locals1();
__locals1.y = 123;
D d = new D(__locals1.__Method1);
}
class __Locals1
{
public int y;
public void __Method1() {
Console.WriteLine(y);
}
}
}

最后,如下匿名方法将捕获this,以及具有不同生存期的两个局部变量。

class Test
{
int x;
void F() {
int y = 123;
for (int i = 0; i < 10; i++) {
int z = i * 2;
D d = delegate { Console.WriteLine(x + y + z); };
}
}
}

在这里,编译器将为每个语句块生成类,在这些语句块中局部变量将被捕获,而在不同块中的局部变量将会有独立的生存期。

__Locals2的实例,编译器为内部语句块生成的类,包含局部变量z和引用__Locals1实例的字段。__Locals1的实例,编译器为外部语句块生成的类,包含局部变量y和引用封闭函数成员的this的字段。通过这些数据结构,你可以通过__Locals2的一个实例到达所有被捕获的局部变量,并且匿名方法的代码可以作为那个类的实例方法而实现。

class Test
{
void F() {
__locals1 = new __Locals1();
__locals1.__this = this;
__locals1.y = 123;
for (int i = 0; i < 10; i++) {
__locals2 = new __Locals2();
__locals2.__locals1 = __locals1;
__locals2.z = i * 2;
D d = new D(__locals2.__Method1);
}
}
class __Locals1
{
public Test __this;
public int y;
}
class __Locals2
{
public __Locals1 __locals1;
public int z;
public void __Method1() {
Console.WriteLine(__locals1.__this.x + __locals1.y + z);
}
}
}

(匿名方法完)


以上就是C# 2.0 Specification(匿名方法)(二)的内容,更多相关内容请关注PHP中文网(www.php.cn)!


声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
汎用性のある.NET言語としてのC#:アプリケーションと例汎用性のある.NET言語としてのC#:アプリケーションと例Apr 26, 2025 am 12:26 AM

C#は、エンタープライズレベルのアプリケーション、ゲーム開発、モバイルアプリケーション、Web開発で広く使用されています。 1)エンタープライズレベルのアプリケーションでは、C#がasp.netcoreにWebAPIを開発するためによく使用されます。 2)ゲーム開発では、C#がUnityエンジンと組み合わされて、ロールコントロールやその他の機能を実現します。 3)C#は、コードの柔軟性とアプリケーションのパフォーマンスを改善するために、多型と非同期プログラミングをサポートします。

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#コードの実行を管理し、ガベージコレクション、タイプの安全性、その他のサービスを提供し、効率的でクロスプラットフォームの操作を保証します。

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 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser は、オンライン試験を安全に受験するための安全なブラウザ環境です。このソフトウェアは、あらゆるコンピュータを安全なワークステーションに変えます。あらゆるユーティリティへのアクセスを制御し、学生が無許可のリソースを使用するのを防ぎます。

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

DVWA

DVWA

Damn Vulnerable Web App (DVWA) は、非常に脆弱な PHP/MySQL Web アプリケーションです。その主な目的は、セキュリティ専門家が法的環境でスキルとツールをテストするのに役立ち、Web 開発者が Web アプリケーションを保護するプロセスをより深く理解できるようにし、教師/生徒が教室環境で Web アプリケーションを教え/学習できるようにすることです。安全。 DVWA の目標は、シンプルでわかりやすいインターフェイスを通じて、さまざまな難易度で最も一般的な Web 脆弱性のいくつかを実践することです。このソフトウェアは、

EditPlus 中国語クラック版

EditPlus 中国語クラック版

サイズが小さく、構文の強調表示、コード プロンプト機能はサポートされていません

VSCode Windows 64 ビットのダウンロード

VSCode Windows 64 ビットのダウンロード

Microsoft によって発売された無料で強力な IDE エディター