検索
ホームページバックエンド開発C#.Net チュートリアルC# におけるリフレクションとダイナミックの最適な組み合わせの例

この記事では、主に C# におけるリフレクションとダイナミックの最適な組み合わせのサンプル コードを紹介します。必要な方は参考にしてください。

リフレクション テクノロジは C# で広く使用されています。理解している場合は、次の段落の説明を読んでください。そうでない場合は、次の段落をスキップしてください。広告: 私の記事を気に入ってくださったお友達は、私のブログに注目してください。これは私の執筆モチベーションの向上にも役立ちます。

反省:美しい女性やハンサムな男性に背を向けているが、振り返って注意深く観察したり研究したりすることができないとき(まったくの架空の話、偶然や類似点)、小さな鏡があなたのニーズを満たすことができます。 C# プログラミングのプロセスでは、他の人が作成した DLL クラス ライブラリを使用したいのに、プログラムのドキュメントがないという同じような状況に遭遇することがよくあります。このとき、C# ランタイムが提供する関数を通じて、 dll クラス ライブラリを使用できます。ライブラリをプログラムにロードし、dll のすべての部分を学習します。これは C# での反映です。

個人的に、リフレクションの最も顕著な利点または合理性は、プログラムの元のコードを変更することなく、プログラム関数の動的調整 (実行時の動的オブジェクトの作成) だと思います。

例:


 interface IRun {
  void Run();
 }
 class Person : IRun
 {
  public void Run()
  {
   Console.WriteLine("走,去LOL啊!");
  }
 }
 class Car : IRun
 {
  public void Run()
  {
   Console.WriteLine("呜...........");
  }
 }
 class Program
 {
  static void Main(string[] args)
  {
   IRun e = new Person();
   e.Run();
   Console.ReadLine();
  }
 }

上記 Run 機能は必ずしも person によって実行されるわけではありません。Car が必要な場合もあれば、Personal が必要な場合もあります。一般的な解決策は、次のように if などの判断構造を追加することです:


 static void Main(string[] args)
  {
   Console.WriteLine("请输入:Car或Person");
   string type = Console.ReadLine();
   IRun e = null;
   if ("Car" == type)
   {
    e = new Car();
   }else if("Person" == type)
   {
    e = new Person();
   }
   if(null != e)
    e.Run();
   Console.ReadLine();
  }

この構造は現在のニーズを解決しますが、堅牢ではありません。 IRun インターフェースの実装と関連クラスの継承の増加に伴い、上記の判定構造も急速に増大するでしょう。オブジェクト指向プログラミングと設計パターンが従う主要な原則の 1 つは、変換をカプセル化することであるため、上記のプログラムは変更にうまく対処できません。ここでは「デザインパターン」の知識は関与しません。そのため、以下のサンプルコードは上記のプログラムを簡略化するためのものであり、意図的にデザインパターンに関する知識を適用するものではありません。以下の通り:


 static void Main(string[] args)
  {
   Console.WriteLine("请输入:Car或Person");
   string type = Console.ReadLine();
   string classPath = String.Format("namespace.{0}", type);
   IRun e = Activator.CreateInstance(null, classPath).Unwrap() as IRun;

   if(null != e)
    e.Run();
   Console.ReadLine();
  }

上記の変更後、プログラムはユーザーの入力に基づいて Activator.CreateInstance を介して IRun のインスタンスを作成できるようになり、IRun 実装者の数が増加してもプログラムは変更されなくなります。反省によって上記のメリットが得られる、これが「反省の存在の合理性」だと私は考えています。

Activator と Assembly は、オブジェクトを作成するためのリフレクション メソッドを実装します

リフレクション メソッドでのオブジェクトの作成は、Activator.CreateInstance (静的) と Assembly.CreateInstance (非静的) を通じて実現できますが、そのうち Assembly.CreateInstance は依然として呼び出されます内部的には Activator.CreateInstance。

動的に作成されるタイプ オブジェクトが現在のアセンブリ内にあるかどうかに応じて、リフレクションによって作成されるオブジェクトは、アセンブリ内でのタイプ オブジェクトの作成とアセンブリ外でのタイプ オブジェクトの作成に分けられます。

アセンブリ内に型オブジェクトを作成する


  private static void ReflectionIRun1(string className)
  {
   string classPath = String.Format("namespace.{0}", className);
   //参数 null ,指出所要创建类型对象位于当前程序集 
   var handler = Activator.CreateInstance(null, classPath);
   IRun e = (IRun)handler.Unwrap();
   Console.WriteLine(e.Run());
  }
  private static void ReflectionIRun2(string className)
  {
   string classPath = String.Format("namespace.{0}", className);
   //typeof(IRun).Assembly 获取 IRun 类型所在的程序集
   object obj = typeof(IRun).Assembly.CreateInstance(null, classPath);
   IRun e = (IRun)obj;
   Console.WriteLine(e.Run());
  }

アセンブリの外に型オブジェクトを作成する

以下に示すように、クラス ライブラリ (別のアセンブリ) をプロジェクトに追加します:

ボスを追加するクラスは次のとおりです。


namespace Lib
{
 public class Boss
 {
  private string name = "老大";
  
  public string Name{
   get {return name;}
  }
  public string Talk()
  {
   return "你们都被开除了......";
  }
  //老板不会算账,总是多付钱,所以很有自知之明的将Payfor设为private,防止外部人员调用
  private int Payfor(int total)
  {
   return total + 10;
  }
 }
}

Boss オブジェクトを取得する前に、まず Lib への参照を追加します。 取得の例は次のとおりです。


 private static void ReflectionBoss1()
  {
   string classPath ="Lib.Boss";
   //"Lib" 参数指明要加载的程序集(即要创建的对象类型在哪个程序集中定义)
   var handler = Activator.CreateInstance("Lib", classPath);
   Boss b = handler.Unwrap() as Boss;
   Console.WriteLine(b.Talk());
  }
  private static void ReflectionBoss2()
  {
   string classPath ="Lib.Boss";
   //Assembly.Load("Lib") 加载的程序集(即要创建的对象类型在哪个程序集中定义)
   var assembly = Assembly.Load("Lib");
   Boss b = (Boss)assembly.CreateInstance(classPath);
   Console.WriteLine(b.Talk());
  }

CLR がアセンブリを検索して配置する方法については、リフレクション中にロードされるため、リフレクションに関する知識については MSDN を参照してください。

リフレクション アクセス フィールドとメソッド (プロパティ) の呼び出し

リフレクションは、オブジェクトを動的に作成するのに役立つだけでなく、C# のバージョンが異なるため、特定のメソッドが動的にアクセスするのにも役立ちます。変更または拡張についての詳細な内容については、MSDN を参照してください。以下は簡単な例です (標準的な使用法)。

上司の名前を変更します。例: 」 '


 private static void ReflectionBoss1()
  {
   string classPath = "Lib.Boss";
   //"Lib" 参数指明要加载的程序集(即要创建的对象类型在哪个程序集中定义)
   var handler = Activator.CreateInstance("Lib", classPath);
   Boss b = handler.Unwrap() as Boss;
   //关键代码
   FieldInfo f = b.GetType().GetField("name", BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.Instance);
   f.SetValue(b, "小二");
   Console.WriteLine("{0}:{1}", b.Name, b.Talk());
  }

出力:

上司にお金を支払わせる:


private static void ReflectionBoss1()
  {
   string classPath = "Lib.Boss";
   //"Lib" 参数指明要加载的程序集(即要创建的对象类型在哪个程序集中定义)
   var handler = Activator.CreateInstance("Lib", classPath);
   Boss b = handler.Unwrap() as Boss;
   //关键代码
   MethodInfo method = b.GetType().GetMethod("Payfor", BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Instance);
   object money = method.Invoke(b, new object[] { 10 });
   Console.WriteLine("DW039:老大给我报销10元钱车费......");
   Console.WriteLine("{0}:.....,算不清了,给你这些吧。",b.Name);
   Console.WriteLine("DW039:......");
   Console.WriteLine("{0}:{1}", b.Name,money);
   Console.WriteLine("DW039:老大你真棒!");
  }

出力:

ダイナミックとリフレクション 2なぜなら、Reflection は実行時の型操作であるため、プログラミング時に型の不確実性の問題に直面するからです。前回の記事「C# 匿名オブジェクト (匿名型)、Var、動的型 Dynamic」によると、動的動的型と私たちが作成したリフレクション プログラムを組み合わせることで、プログラム ロジックを大幅に最適化できます (保護レベルによって制限されているコードへのアクセスは制限されません)この範囲)。

上記のコードの最適化:

private static void ReflectionBoss1()
  {
   string classPath ="Lib.Boss";
   var handler = Activator.CreateInstance("Lib", classPath);
   dynamic b = handler.Unwrap();
   Console.WriteLine(b.Talk());
  }
  private static void ReflectionBoss2()
  {
   string classPath ="Lib.Boss";
   var assembly = Assembly.Load("Lib");
   dynamic b = assembly.CreateInstance(classPath);
   Console.WriteLine(b.Talk());
  }

動的動的型オブジェクト b を使用してリフレクションを呼び出し、直接呼び出すことができるオブジェクトのプロパティとメソッドを取得することで、頻繁な型変換操作を排除します。

リフレクションの一般的なアプリケーションシナリオ

アプリケーション シナリオ 私が最も印象に残ったのは、MS Petshop の例です。SQL Server データベースから Oracle データベースに切り替えると、リフレクションはさまざまなデータ アクセス層を取得します。ただし、実際のプロジェクトでデータベースが途中で切り替わる状況に遭遇したことはありません。他のアプリケーション シナリオも基本的には上記の例と同様です。さらに多くのアプリケーション シナリオを見つけた場合は、3ks を追加してください。

リフレクションの長所と短所

利点: リフレクションによりプログラムがより柔軟になります

欠点: リフレクションの実行が比較的遅い

リフレクションが通常のプログラムよりも遅いことについては、テストしていませんし、行う予定もありません。現実には、Ms はダイナミックの使用を推奨しており、Mvc は人気があり、継続的に CLR を最適化し、マシンのパフォーマンスを向上させているため、開発中にリフレクション パフォーマンスの問題をあまり考慮する必要はありません。作成したプログラムの実行速度にボトルネックがある場合 (プログラムが適切に作成されていることをまず確認する必要があります)、データベースの最適化、データ キャッシュ、Web キャッシュ、負荷分散などのテクノロジを研究する方が現実的だと思います。

以上がC# におけるリフレクションとダイナミックの最適な組み合わせの例の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
C#と.NET:2つの関係を理解し​​ますC#と.NET:2つの関係を理解し​​ますApr 17, 2025 am 12:07 AM

C#と.NETの関係は切り離せませんが、同じものではありません。 C#はプログラミング言語であり、.NETは開発プ​​ラットフォームです。 C#は、コードの書き込み、.NETの中間言語(IL)にコンパイルされ、.NET Runtime(CLR)によって実行されるために使用されます。

c#.netの継続的な関連性:現在の使用法を見るc#.netの継続的な関連性:現在の使用法を見るApr 16, 2025 am 12:07 AM

C#.NETは、複数のアプリケーション開発をサポートする強力なツールとライブラリを提供するため、依然として重要です。 1)C#は.NETフレームワークを組み合わせて、開発を効率的かつ便利にします。 2)C#のタイプの安全性とゴミ収集メカニズムは、その利点を高めます。 3).NETは、クロスプラットフォームの実行環境とリッチAPIを提供し、開発の柔軟性を向上させます。

Webからデスクトップまで:C#.NETの汎用性Webからデスクトップまで:C#.NETの汎用性Apr 15, 2025 am 12:07 AM

c#.netisversatileforbothwebanddesktopdevelopment.1)forweb、useasp.netfordynamicapplications.2)fordesktop、equindowsorwpfforrichinterfaces.3)usexamarinforcross-platformdeveliment、enabling deshacrosswindows、

c#.net and the Future:新しいテクノロジーへの適応c#.net and the Future:新しいテクノロジーへの適応Apr 14, 2025 am 12:06 AM

C#と.NETは、継続的な更新と最適化を通じて、新しいテクノロジーのニーズに適応します。 1)C#9.0および.NET5は、レコードタイプとパフォーマンスの最適化を導入します。 2).Netcoreは、クラウドネイティブおよびコンテナ化されたサポートを強化します。 3)ASP.Netcoreは、最新のWebテクノロジーと統合されています。 4)ML.NETは、機械学習と人工知能をサポートしています。 5)非同期プログラミングとベストプラクティスはパフォーマンスを改善します。

c#.netはあなたにぴったりですか?その適用性の評価c#.netはあなたにぴったりですか?その適用性の評価Apr 13, 2025 am 12:03 AM

c#.netissuitableforenterprise-levelApplicationsとsystemduetoitsSystemdutyping、richlibraries、androbustperformance.

.NET内のC#コード:プログラミングプロセスの調査.NET内のC#コード:プログラミングプロセスの調査Apr 12, 2025 am 12:02 AM

.NETでのC#のプログラミングプロセスには、次の手順が含まれます。1)C#コードの作成、2)中間言語(IL)にコンパイルし、3).NETランタイム(CLR)によって実行される。 .NETのC#の利点は、デスクトップアプリケーションからWebサービスまでのさまざまな開発シナリオに適した、最新の構文、強力なタイプシステム、および.NETフレームワークとの緊密な統合です。

C#.NET:コアの概念とプログラミングの基礎を探るC#.NET:コアの概念とプログラミングの基礎を探るApr 10, 2025 am 09:32 AM

C#は、Microsoftによって開発された最新のオブジェクト指向プログラミング言語であり、.NETフレームワークの一部として開発されています。 1.C#は、カプセル化、継承、多型を含むオブジェクト指向プログラミング(OOP)をサポートしています。 2。C#の非同期プログラミングは非同期を通じて実装され、適用応答性を向上させるためにキーワードを待ちます。 3. LINQを使用してデータ収集を簡潔に処理します。 4.一般的なエラーには、null参照の例外と、範囲外の例外インデックスが含まれます。デバッグスキルには、デバッガーと例外処理の使用が含まれます。 5.パフォーマンスの最適化には、StringBuilderの使用と、不必要な梱包とボクシングの回避が含まれます。

テストC#.NETアプリケーション:ユニット、統合、およびエンドツーエンドテストテストC#.NETアプリケーション:ユニット、統合、およびエンドツーエンドテストApr 09, 2025 am 12:04 AM

C#.NETアプリケーションのテスト戦略には、ユニットテスト、統合テスト、エンドツーエンドテストが含まれます。 1.単位テストにより、コードの最小ユニットがMSTEST、ヌニット、またはXUNITフレームワークを使用して独立して動作することを保証します。 2。統合テストでは、一般的に使用されるシミュレートされたデータと外部サービスを組み合わせた複数のユニットの機能を検証します。 3.エンドツーエンドのテストでは、ユーザーの完全な操作プロセスをシミュレートし、通常、セレンは自動テストに使用されます。

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

AI Hentai Generator

AI Hentai Generator

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

ホットツール

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

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

Safe Exam Browser

Safe Exam Browser

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

AtomエディタMac版ダウンロード

AtomエディタMac版ダウンロード

最も人気のあるオープンソースエディター

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

Dreamweaver Mac版

Dreamweaver Mac版

ビジュアル Web 開発ツール