ホームページ バックエンド開発 C#.Net チュートリアル C# の反変性と共分散の詳細な説明

C# の反変性と共分散の詳細な説明

Sep 02, 2017 pm 02:32 PM
.net 詳しい説明

この記事では主に C# の反転と共分散の関連情報を詳しく紹介します。興味のある方は参考にしてください。

この記事では、これらの式に慣れていない場合は、完全な知識システムの構築に役立つように、私の記事「委任と匿名委任」と「匿名委任とラムダ式」を参照してください。

C# の誕生から開発、成長に至る過程では、常に新しい知識ポイントが導入されます。反変性と共分散は C# 独自のものではないため、後で導入します。反変性と共分散性は Java にも存在します。今後、Java の反変性と共分散についても記事を書きますので、興味のある方は注目してください。

反変性と共分散は抽象的で奥深いように聞こえるかもしれませんが、実際は非常に単純です。以下のコードを見てください:


class Person
 {

 }
 class Student : Person
 {

 }
 class Teacher: Person
 {

 }
 
 class Program
 {
  static void Main(string[] args)
  {
   List<Person> plist = new List<Person>();
   plist = new List<Student>();
   plist = new List<Teacher>();
}
}
ログイン後にコピー

上記のコードでは、plist = new List() と plist = new List() という 2 つの文によりコンパイル エラーが発生します。 Person は Student/Teacher の親クラスですが、List 型は List 型の親クラスではないため、上記の代入ステートメントは型変換エラーを報告します。

上記のような代入操作は、C# 4.0 より前では許可されませんでした。許可されない理由としては、タイプ セーフティが主な要因です。以下のサンプルコードを見てください:


List<Person> plist = new List<Student>();
plist.Add(new Person());
plist.Add(new Student());
plist.Add(new Teacher());
ログイン後にコピー

次の例では、List plist = new List() が代入を許可していることを前提としています。リスト<学生>コレクションです。 plist.Add(new Person())、実際の追加操作は List.Add() を呼び出します。 Person タイプは Student に安全に変換できないため、そのようなコレクション定義は意味をなさず、そのため上記の仮定は当てはまりません。

しかし、C# 4.0 以降は状況が変わりました。「

不可能なことが起こった」ということではなく、アプリケーションの柔軟性に新たな調整が加えられたということです。同様に、上記のプログラムは C# 4.0 ではまだ許可されていませんが、例外が発生します。 C# 4.0 以降、汎用デリゲートおよび汎用インターフェイスで特殊な状況が発生することが許可されています (本質的には、特別な変更は行われていません。これについては後で説明します)。次の例:


delegate void Work<T>(T item);

class Person
{
  public string Name { get; set; }
}
class Student : Person
{
  public string Like { get; set; }
}
class Teacher : Person
{
  public string Teach { get; set; }
}

class Program
{
  static void Main(string[] args)
  {
   Work<Person> worker = (p) => { Console.WriteLine(p.Name); }; ;
   Work<Student> student_worker = (s) => { Console.WriteLine(s.Like); };
   student_worker = worker; //此处编译错误
  }
}
ログイン後にコピー

前述の理論的裏付けによれば、student_worker = worker; の誤りは理解しやすいです。ただし、ここでのプログラムの目的は、worker を Work として機能させることです。将来、student_worker を呼び出すと、実際には waker が呼び出されます。私たちのニーズを満たすために、プログラムは 2 つの側面の処理を実行する必要があります:

1. Student_worker(s) を呼び出すとき、実際に実行されるのは waker(s) であるため、s 変数の型が正常である必要があります。 waker タイプに必要なパラメータに変換されます。

2. Work 型のオブジェクトを Work 型の変数に代入できることをコンパイラーに伝える必要があります。

条件 1student_worker() を呼び出すと、コンパイラーは、パラメーターが Student タイプのオブジェクトである必要があることを要求します。これは、person タイプのオブジェクトに正常に変換できます。

条件 2 では、次のように Woke デリゲート定義を調整する必要があります:


delegate void WorkIn<in T>(T item);
ログイン後にコピー

デリゲート名を WorkIn に変更することは、変更前と変更後のデリゲートを区別するためです。重要な点は です。 in キーワードを追加することで、ジェネリック デリゲートの型パラメーター T をマークし、それをデリゲート メソッドのパラメーターとしてのみ使用します。この時点で、上記のプログラムは正常にコンパイルおよび実行できます。


delegate void WorkIn<in T>(T item);
class Program
 {
  static void Main(string[] args)
  {
   WorkIn woker = (p) => { Console.WriteLine(p.Name); };
   WorkIn student_worker = woker;
   student_worker(new Student() { Name="tom", Like="C#" });

  }
 }
ログイン後にコピー

型パラメータがサブタイプである必要があり、代入型パラメータが親型値であることが許可される状況は、反変性と呼ばれます。 C# の反変性では、ジェネリックの型パラメーターをマークする必要があります。反変性は反変性と呼ばれますが、形式的には親クラスのオブジェクトがサブクラス変数に割り当てられているように見えるだけで、本質的にはメソッドが呼び出されたときのパラメーターの型変換です。 Student s = new Person()、これは不可能です。これは反変ではなく、エラーです。

上記のコードを次の形式に変換できれば、現象よりも本質が重要です。

以上がC# の反変性と共分散の詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホット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衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

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

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

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

C++のmode関数の詳しい解説 C++のmode関数の詳しい解説 Nov 18, 2023 pm 03:08 PM

C++ のモード関数の詳細な説明 統計において、モードとは、一連のデータ内で最も頻繁に現れる値を指します。 C++ 言語では、モード関数を記述することによって、任意のデータセット内のモードを見つけることができます。モード関数はさまざまな方法で実装できます。一般的に使用される 2 つの方法を以下で詳しく紹介します。 1 つ目の方法は、ハッシュ テーブルを使用して各数値の出現回数をカウントすることです。まず、各数値をキー、出現回数を値とするハッシュ テーブルを定義する必要があります。次に、特定のデータセットに対して次を実行します。

Win11での管理者権限の取得について詳しく解説 Win11での管理者権限の取得について詳しく解説 Mar 08, 2024 pm 03:06 PM

Windows オペレーティング システムは世界で最も人気のあるオペレーティング システムの 1 つであり、その新バージョン Win11 が大きな注目を集めています。 Win11 システムでは、管理者権限の取得は重要な操作であり、管理者権限を取得すると、ユーザーはシステム上でより多くの操作や設定を実行できるようになります。この記事では、Win11システムで管理者権限を取得する方法と、権限を効果的に管理する方法を詳しく紹介します。 Win11 システムでは、管理者権限はローカル管理者とドメイン管理者の 2 種類に分かれています。ローカル管理者はローカル コンピュータに対する完全な管理権限を持っています

Oracle SQLの除算演算の詳細説明 Oracle SQLの除算演算の詳細説明 Mar 10, 2024 am 09:51 AM

OracleSQL の除算演算の詳細な説明 OracleSQL では、除算演算は一般的かつ重要な数学演算であり、2 つの数値を除算した結果を計算するために使用されます。除算はデータベース問合せでよく使用されるため、OracleSQL での除算演算とその使用法を理解することは、データベース開発者にとって重要なスキルの 1 つです。この記事では、OracleSQL の除算演算に関する関連知識を詳細に説明し、読者の参考となる具体的なコード例を示します。 1. OracleSQL での除算演算

C++の剰余関数の詳しい解説 C++の剰余関数の詳しい解説 Nov 18, 2023 pm 02:41 PM

C++ の剰余関数の詳しい説明 C++ では、剰余演算子 (%) を使用して、2 つの数値を除算した余りを計算します。これは、オペランドが任意の整数型 (char、short、int、long など) または浮動小数点数型 (float、double など) になる二項演算子です。剰余演算子は、被除数と同じ符号の結果を返します。たとえば、整数の剰余演算の場合、次のコードを使用して実装できます。

Vue.nextTick関数の使い方と非同期更新での応用について詳しく解説 Vue.nextTick関数の使い方と非同期更新での応用について詳しく解説 Jul 26, 2023 am 08:57 AM

Vue.nextTick 関数の使い方と非同期更新での応用について詳しく説明 Vue の開発では、DOM を変更した直後にデータを更新したり、関連する操作が必要になったりするなど、データを非同期で更新する必要がある状況によく遭遇します。データが更新された直後に実行されます。このような問題を解決するために登場したのが、Vue が提供する .nextTick 関数です。この記事では、Vue.nextTick 関数の使用法を詳しく紹介し、コード例と組み合わせて、非同期更新でのアプリケーションを説明します。 1.Vue.nex

PHPモジュロ演算子の役割と使い方を詳しく解説 PHPモジュロ演算子の役割と使い方を詳しく解説 Mar 19, 2024 pm 04:33 PM

PHP のモジュロ演算子 (%) は、2 つの数値を除算した余りを取得するために使用されます。この記事では、モジュロ演算子の役割と使用法について詳しく説明し、読者の理解を深めるために具体的なコード例を示します。 1. モジュロ演算子の役割 数学では、整数を別の整数で割ると、商と余りが得られます。たとえば、10 を 3 で割ると、商は 3 になり、余りは 1 になります。モジュロ演算子は、この剰余を取得するために使用されます。 2. モジュロ演算子の使用法 PHP では、% 記号を使用してモジュロを表します。

いくつかの .NET オープンソース AI および LLM 関連プロジェクト フレームワークを共有する いくつかの .NET オープンソース AI および LLM 関連プロジェクト フレームワークを共有する May 06, 2024 pm 04:43 PM

現在、人工知能(AI)技術の開発は本格化しており、さまざまな分野で大きな可能性と影響力を発揮しています。本日、Dayao は、参考にしていただけるよう、4 つの .NET オープン ソース AI モデル LLM 関連プロジェクト フレームワークを共有します。 https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.mdSemanticKernelSemanticKernel は、OpenAI、Azure などの大規模言語モデル (LLM) を統合するように設計されたオープン ソース ソフトウェア開発キット (SDK) です。

C# の雇用の見通しはどのようなものですか? C# の雇用の見通しはどのようなものですか? Oct 19, 2023 am 11:02 AM

初心者でも経験豊富なプロフェッショナルでも、C# をマスターすることでキャリアへの道が開かれます。

See all articles