日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Reflection

發布時間:2025/6/15 编程问答 17 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Reflection 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
      • 1.反射
        • 1.1 System.Type類
        • 1.2 使用System.Object.GetType()得到Type的引用
        • 1.3 使用typeof()得到Type引用
        • 1.4 使用System.Type.GetType()得到Type引用
      • 2.構建自定義的元數據查看器
        • 2.1 反射方法
        • 2.2 反射字段和屬性
        • 2.3 反射實現的接口
        • 2.4 顯示其他信息
        • 2.5 反射泛型信息
        • 2.6 反射方法參數和返回值
      • 3.動態加載程序集
      • 4.反射共享程序集
      • 5.晚期綁定
      • 6.使用早期綁定反射特性
      • 7.使用晚期綁定反射特性
      • 8.反射、晚期綁定使用背景
      • 9.反射的性能

1.反射

在.Net中,反射(reflection)是一個運行庫類型發現的過程。通過反射可以得到一個給定.dll或.exe程序集所包含的所有類型的列表,其中包括類型定義的方法、字段、屬性和事件,也可以動態發現一組給定類型支持的接口、方法的參數或其他相關細節(基類、命名空間、清單數據等)。
System.Reflection命名空間成員示例:

類型作用
Assembly該抽象類包含了許多靜態方法,通過它可以加載、了解和操縱一個程序集
AssemblyName使用該類可以找到大量隱藏在程序集的身份中的細節(版本信息、區域信息等)
EventInfo該抽象類保存給定事件的信息
FieldInfo該抽象類保存給定字段的信息
MemberInfo該類是抽象類,它為EventInfo、FieldInfo、MethodInfo和PropertyInfo類型定義了公共的行為
MethodInfo該抽象類保存給定方法的信息
Module該抽象類可以訪問多文件程序集中的給定模塊
ParameterInfo該類保存給定參數的信息
PropertyInfo該抽象類保存給定屬性的信息

1.1 System.Type類

System.Type的部分成員:

類型作用
IsAbstract、Isarray、IsClass、IsCOMObject、IEnum、
IsGenericTypeDefinition、IsGenericParameter、
IsInterface、IsPrimitive、IsNestedPrivate、
IsNestedPublic、IsSealed、IsValueType
用于發現所引用類型的基本特性
GetConstructors()、GetEvents()、GetFields()、
GetInterfaces()、GetMembers()、GetMethods()、
GetNestedType()、GetProperties()
得到接口、方法、屬性等的數組(每個方法都有單數版本,如GetMethod())
FindMembers()該方法根據查詢條件返回一個MemberInfo類型的數組
GetType()該靜態方法返回一個Type實例,給定一個字符串名稱
InvokeMember該方法允許對給定項目的晚期綁定

1.2 使用System.Object.GetType()得到Type的引用

使用System.Object定義的GetType()方法,返回一個表示當前對象元數據的Type類的實例。

SportsCar sc = new SportsCar(); Type t = sc.GetType(); // 需要創建實例,需知道類型的編譯時信息

1.3 使用typeof()得到Type引用

另一種獲取類型信息的方法是使用C# typeof操作符。

Type t = typeof(SportsCar); // 無需創建實例,需知道類型的編譯時信息

1.4 使用System.Type.GetType()得到Type引用

使用System.Type.GetType()得到Type引用,不需要得到正從中提取元數據的類型的編譯時信息。

// 指定兩個參數,一個用來控制當前類型找不到時是否拋出異常,另一個用來指示是否區分字符串大小寫 Type t = Type.GetType("Carlibrary.SportsCar", false, false) // 要得到外部程序集中類型的類型信息,字符串必須使用完全限定名,加上類型所在程序集的友好名字(逗號分隔) Type t = Type.GetType("Carlibrary.SportsCar, Carlibrary") // 要得到當前程序集中嵌套枚舉的類型信息,使用+來標記 Type t = Type.GetType("Carlibrary.JamesBondCar+SpyOption") // 獲取嵌套在JamesBondCar類中的枚舉類型(SpyOption

2.構建自定義的元數據查看器

需要為反射導入命名空間:

using System.Reflection;

2.1 反射方法

Type.GetMethods()返回一個System.Reflection.MethodInfo類型的數組,并使用foreach循環枚舉:

using System; using System.Reflection; public interface IA { void M1(); }; public interface IB { void M2(); }; class SportsCar : IA { public int a = 0; public double b = 3.14; public string S { get; set; } public void A(int a) { } public void B() { } public void C() { } public void M1() { } } class Program { static void ListMethods(Type t) { Console.WriteLine("*** Methods ***"); MethodInfo[] mi = t.GetMethods(); foreach (MethodInfo m in mi) Console.WriteLine($"->{m.Name}"); } static void Main() { SportsCar sc = new SportsCar(); Type t = sc.GetType(); ListMethods(t); Console.ReadKey(); } }

output

*** Methods *** ->get_S ->set_S ->A ->B ->C ->ToString ->Equals ->GetHashCode ->GetType

2.2 反射字段和屬性

static void ListFields(Type t) // 字段 { Console.WriteLine("*** Fields ***"); var fieldNames = from f in t.GetFields() select f.Name; foreach (var name in fieldNames) Console.WriteLine($"->{name}"); } static void ListProps(Type t) // 屬性 { Console.WriteLine("*** Methods ***"); var propsNames = from p in t.GetProperties() select p.Name; foreach (var name in propsNames) Console.WriteLine($"->{name}"); } static void Main() { SportsCar sc = new SportsCar(); Type t = sc.GetType(); ListFields(t); ListProps(t) Console.ReadKey(); }

output

*** Fields *** ->a ->b *** Propertys *** ->S

2.3 反射實現的接口

// 顯示當前類實現的接口 static void ListInterfaces(Type t) { Console.WriteLine("*** Interfaces ***"); var ifacesNames = from i in t.GetInterfaces() select i.Name; foreach (var name in ifacesNames) Console.WriteLine($"->{name}"); } static void Main() { SportsCar sc = new SportsCar(); Type t = sc.GetType();; ListInterfaces(t); Console.ReadKey(); }

output

*** Interfaces *** ->IA

2.4 顯示其他信息

顯示關于傳入類型的各種統計信息(表示該類型是否是泛型,基類是什么,類型是否密封等等)

static void ListVariousStats(Type t) {Console.WriteLine("*** Various Statistics ***");Console.WriteLine($"Base class is: {t.BaseType}"); Console.WriteLine($"abstract? {t.IsAbstract}"); Console.WriteLine($"sealed? {t.IsSealed}"); Console.WriteLine($"generic? {t.IsGenericTypeDefinition}"); Console.WriteLine($"class? {t.IsClass}"); } static void Main() { SportsCar sc = new SportsCar(); Type t = sc.GetType(); ListVariousStats(t); Console.ReadKey(); }

output

*** Various Statistics *** Base class is: System.Object abstract? False sealed? False generic? False class? True

2.5 反射泛型信息

如果調用Type.GetType()來獲取泛型類型的元數據描述,就必須使用包含反引號(`)加上數值的語法來表示類型支持的類型參數個數

using System.Collection.Generic.List`1 // 反射List<T>元數據描述 using System.Collection.Generic.Dictionary`2 // 反射Dictionary<TKey, TValue>元數據描述

2.6 反射方法參數和返回值

使用MethodInfo類型提供的ReturnType屬性和GetParameters()方法,列出方法的返回類型和輸入參數類型。

static void ListMethods(Type t) { Console.WriteLine("*** Methods ***"); MethodInfo[] mi = t.GetMethods(); foreach (MethodInfo m in mi) { string retVal = m.ReflectedType.FullName; string paramInfo = "( "; foreach (ParameterInfo pi in m.GetParameters()) { paramInfo += string.Format($"{pi.ParameterType} {pi.Name}"); } paramInfo += " )"; Console.WriteLine($"->{retVal} {m.Name} {paramInfo}"); } }

output

*** Methods *** ->SportsCar get_S ( ) ->SportsCar set_S ( System.String value ) ->SportsCar A ( System.Int32 a ) ->SportsCar B ( ) ->SportsCar C ( ) ->SportsCar M1 ( ) ->SportsCar ToString ( ) ->SportsCar Equals ( System.Object obj ) ->SportsCar GetHashCode ( ) ->SportsCar GetType ( )

或者使用以下語法(每一個XXXInfo類型都重寫了ToString()方法)

static void ListMethods(Type t) { Console.WriteLine("*** Methods ***"); var fieldNames = from f in t.GetMethods() select f; foreach (var name in fieldNames) Console.WriteLine($"->{name}"); }

output

*** Methods *** ->System.String get_S() ->Void set_S(System.String) ->Void A(Int32) ->Void B() ->Void C() ->Void M1() ->System.String ToString() ->Boolean Equals(System.Object) ->Int32 GetHashCode() ->System.Type GetType()

3.動態加載程序集

使用System.Reflection下的Assembly類,動態加載程序集,并找出關于程序集自身的屬性。

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Reflection; using System.IO; // For FileNotFoundException definition. namespace ExternalAssemblyReflector { class Program { #region Helper function static void DisplayTypesInAsm(Assembly asm) { Console.WriteLine("\n***** Types in Assembly *****"); Console.WriteLine("->{0}", asm.FullName); Type[] types = asm.GetTypes(); foreach (Type t in types) Console.WriteLine("Type: {0}", t); Console.WriteLine(""); } #endregion static void Main(string[] args) { Console.WriteLine("***** External Assembly Viewer *****"); string asmName = ""; Assembly asm = null; do { Console.WriteLine("\nEnter an assembly to evaluate"); Console.Write("or enter Q to quit: "); // Get name of assembly. asmName = Console.ReadLine(); // Does user want to quit? if (asmName.ToUpper() == "Q") { break; } // Try to load assembly. try { asm = Assembly.LoadFrom(asmName); DisplayTypesInAsm(asm); } catch { Console.WriteLine("Sorry, can't find assembly."); } } while (true); } } }

加載程序集方法Load()與LoadFrom()的區別:

Assembly.Load()Assembly.LoadFrom()
使用程序集友好名稱(其dll文件應置于\bin\Debug目錄下)使用絕對路徑
Assembly.Load("CarLibrary")Assembly.LoadFrom("C:\MyApp\MyAsm.dll")

4.反射共享程序集

Assembly.Load()的一種重載允許指定一個區域設置(為本地化程序集)、一個版本號和公鑰標記值(為共享程序集)。整體來說,識別一個程序集的一組術語稱為顯示名稱(display name),顯示名稱以程序集友好名稱開頭。

Name(,Version = major.minor.build.revision)(,culture = culture token)(,PublicKeyToken = public key token)

如:

Assembly a = Assembly.Load(@"CarLibrary, Version = 1.0.0.0, PublicKeyToken = null, Culture = """);

可以使用System.Reflection命名空間提供的AssemblyName類型創建顯示名稱。

AssemblyName asmName; asmName = new AssemblyName(); asmName.Name = "CarLibrary"; Version v = new Version("1.0.0.0"); asmName.Version = v; Assembly a = Assembly.Load(asmName); namespace SharedAsmReflector {public class SharedAsmReflector { #region DisplayInfo helper method private static void DisplayInfo(Assembly a) { Console.WriteLine("***** Info about Assembly *****"); Console.WriteLine("Loaded from GAC? {0}", a.GlobalAssemblyCache); Console.WriteLine("Asm Name: {0}", a.GetName().Name); Console.WriteLine("Asm Version: {0}", a.GetName().Version); Console.WriteLine("Asm Culture: {0}", a.GetName().CultureInfo.DisplayName); Console.WriteLine("\nHere are the public enums:"); // Use a LINQ query to find the public enums. Type[] types = a.GetTypes(); var publicEnums = from pe in types where pe.IsEnum && pe.IsPublic select pe; foreach (var pe in types) { Console.WriteLine(pe); } } #endregion static void Main(string[] args) { Console.WriteLine("***** The Shared Asm Reflector App *****\n"); // Load System.Windows.Forms.dll from GAC. GAC:全局程序集緩存 string displayName = null; displayName = "System.Windows.Forms," + "Version=4.0.0.0," + "PublicKeyToken=b77a5c561934e089," + @"Culture="""; Assembly asm = Assembly.Load(displayName); DisplayInfo(asm); Console.WriteLine("Done!"); Console.ReadLine(); } } }

5.晚期綁定

晚期綁定(late binding)是一種創建一個給定類型的實例并在運行時調用其成員,而不需要在編譯時知道它存在的一種技術。即通過編程的方式在內存中加載.NET程序集。
使用Activator.CreateInstance()方法建立一個晚期綁定類型的實例。

namespace LateBindingApp {// 這個程序將加載一個外部庫并使用晚期綁定創建一個對象public class Program{static void Main(string[] args) { Console.WriteLine("***** Fun with Late Binding *****"); // 嘗試加載一個本地CarLibrary副本 Assembly a = null; try { a = Assembly.Load("CarLibrary"); } catch (FileNotFoundException ex) { Console.WriteLine(ex.Message); return; } if (a != null) { // CreateUsingLateBinding(a); InvokeMethodWithArgsUsingLateBinding(a); } Console.ReadLine(); } #region Invoke method with no args static void CreateUsingLateBinding(Assembly asm) { try { // 獲取Minivan類型的元數據 Type miniVan = asm.GetType("CarLibrary.MiniVan"); // 在運行時創建Minivan // 返回System.Object類型,由于未引用CarLibrary.dll,故無法強制轉換 object obj = Activator.CreateInstance(miniVan); Console.WriteLine("Created a {0} using late binding!", obj); // 利用反射獲得CarLibrary中TurboBoost()方法的信息. MethodInfo mi = miniVan.GetMethod("TurboBoost"); // 調用方法(“null”表示沒有參數) mi.Invoke(obj, null); } catch (Exception ex) { Console.WriteLine(ex.Message); } } #endregion #region Invoke method with args static void InvokeMethodWithArgsUsingLateBinding(Assembly asm) { try { // 首先,獲得元數據描述 Type sport = asm.GetType("CarLibrary.SportsCar"); // 創建對象 object obj = Activator.CreateInstance(sport); // 調用包含參數的TurnOnRadio()方法 MethodInfo mi = sport.GetMethod("TurnOnRadio"); mi.Invoke(obj, new object[] { true, 2 }); // 使用object數組存放參數 } catch (Exception ex) { Console.WriteLine(ex.Message); } } #endregion } }

6.使用早期綁定反射特性

using AttributedCarLibrary; //引入AttributedCarLibrary namespace VehicleDescriptionAttributeReader { class Program { static void Main(string[] args) { Console.WriteLine("***** Value of VehicleDescriptionAttribute *****\n"); ReflectOnAttributesWithEarlyBinding(); Console.ReadLine(); } private static void ReflectOnAttributesWithEarlyBinding() { // 獲取Winnebago元數據描述 Type t = typeof(Winnebago); // 使用GetCustomAttributes(bool)獲取所有特性,返回一個對象數組,其中bool值控制是否擴展到繼承鏈 object[] customAtts = t.GetCustomAttributes(false); // 輸出描述 foreach (VehicleDescriptionAttribute v in customAtts) Console.WriteLine("-> {0}\n", v.Description); } } }

7.使用晚期綁定反射特性

using System.Reflection; namespace VehicleDescriptionAttributeReaderLateBinding {class Program { static void Main(string[] args) { Console.WriteLine("***** Value of VehicleDescriptionAttribute *****\n"); ReflectAttributesUsingLateBinding(); Console.ReadLine(); } #region Helper method private static void ReflectAttributesUsingLateBinding() { try { // 加載本地AttributedCarLibrary副本 Assembly asm = Assembly.Load("AttributedCarLibrary"); // 得到VehicleDescriptionAttribute的類型信息 Type vehicleDesc = asm.GetType("AttributedCarLibrary.VehicleDescriptionAttribute"); // 得到Description屬性的類型信息 PropertyInfo propDesc = vehicleDesc.GetProperty("Description"); // 得到程序集中所有類型 Type[] types = asm.GetTypes(); // 遍歷每個類型,得到所有VehicleDescriptionAttributes. foreach (Type t in types) { object[] objs = t.GetCustomAttributes(vehicleDesc, false); // 遍歷每個VehicleDescriptionAttribute并使用晚期綁定輸出描述 foreach (object o in objs) { Console.WriteLine("-> {0}: {1}\n", t.Name, propDesc.GetValue(o, null)); } } } catch (Exception ex) { Console.WriteLine(ex.Message); } } #endregion } }

8.反射、晚期綁定使用背景

  • 首先,可擴展的應用程序必須提供一些輸入手段,允許用戶指定被插入的模塊,這需要動態加載
  • 其次,可擴展的應用程序必須要確定模塊是否支持正確的功能,這需要反射
  • 最后,可擴展的應用程序必須獲取一個需要的基礎架構的引用并調用成員觸發底層功能,這需要晚期綁定?

9.反射的性能

反射時相當強大的機制,允許在運行時發現并使用編譯時還不了解的類型及其成員,但是,反射也存在以下兩個缺點:

  • 反射造成編譯時無法保證類型安全性。 由于反射嚴重依賴于字符串,所以會喪失編譯時的類型安全性。例如,執行type.GetType("int");要求通過反射在程序集中查找名為“int”的類型,代碼會通過編譯,但運行時會返回null,因為CLR只知“System.Int32”,不知“int”。
  • 反射速度慢。
    • 使用反射時,類型及其成員的名稱在編譯時是未知的;要用字符串名稱標識每個類及其成員,然后在運行時發現它們,即使用System.Reflection命名空間中的類型掃描程序集的元數據時,反射機制會不停的執行字符串搜索,且通常執行的是不區分大小的比較,這會進一步影響速度。
    • 使用反射調用一個成員時。比如調用方法,首先必須將實參打包(pack)成一個數組;在內部,反射必須將這些實參解包(unpack)到線程棧上。此外,在調用方法前,CLR必須檢查實參具有正確的數據類型。最后,CLR必須確保調用者有正確的安全權限來訪問被調用的成員。

改善方法:

    • 讓類型從編譯時已知的基類型派生。運行時構造派生類型的實例,將對它的引用放到基類型的變量中(利用轉型),再調用基類型定義的虛方法。
    • 讓類型實現編譯時已知的接口。在運行時構造類型的實例,將對它的引用放到接口類型的變量中(利用轉型),再調用接口定義的方法。

轉載于:https://www.cnblogs.com/jizhiqiliao/p/10649119.html

《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

總結

以上是生活随笔為你收集整理的Reflection的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 72pao成人国产永久免费视频 | 久久亚洲综合国产精品99麻豆精品福利 | 日韩黄色片在线观看 | 小镇姑娘高清播放视频 | 四虎免费影视 | 在线观看黄色动漫 | 国产精品美女一区二区 | 99re国产 | 日产av在线播放 | 最新中文字幕在线观看视频 | 激情综合五月婷婷 | 精品久久不卡 | 国产伦精品一区二区三区网站 | 一区二区三区四区人妻 | 少妇高潮毛片 | 国产欧美一区二区三区国产幕精品 | 红桃av | 永久免费视频网站 | 成人xxxx| 亚洲一区二区三区在线 | 成 人免费va视频 | 丝袜+亚洲+另类+欧美+变态 | 秋霞福利影院 | av成人在线免费观看 | 国产后入又长又硬 | 91精品国产视频 | 羞羞答答av | 成人免费毛片嘿嘿连载视频 | 亚洲精品日日夜夜 | 色狠狠干| 先锋av在线资源 | 少妇人妻真实偷人精品视频 | 高清一区二区三区四区 | 日韩视频免费在线 | 国产专区欧美专区 | 国产高清成人久久 | 久久这里只有精品久久 | 久久性感视频 | 日韩免费网站 | 黄色在线不卡 | 午夜成年人视频 | 丰满人妻中伦妇伦精品app | 国产精品自产拍在线观看 | 日日操av | 亚洲人屁股眼子交1 | 波多野结衣理论片 | 中文字幕在线视频观看 | av猫咪 | 一本—道久久a久久精品蜜桃 | 亚洲AV无码一区二区三区性 | bt天堂新版中文在线地址 | 亚洲激情六月 | 精品免费一区二区 | 精品中文一区二区三区 | 亚洲精品888 | 永久免费54看片 | 日本中文视频 | 午夜在线免费观看 | 第四色影音先锋 | 福利网址在线观看 | 国产乱free国语对白 | 一区二区三区四区视频在线观看 | 欧美极品少妇xxxxⅹ免费视频 | 欧美午夜精品久久久 | 成人两性视频 | 色偷偷综合网 | 亚洲春色另类 | 国产精品99久久久久久www | 蜜臀av性久久久久蜜臀aⅴ涩爱 | 超碰人人射 | 国产精品情侣 | 国产成人精品一区二区三区视频 | 国产成人网| 最新在线黄色网址 | 91丝袜呻吟高潮美腿白嫩 | 国产成人精品视频在线 | 午夜激情在线播放 | 国产精品日韩欧美一区二区三区 | 欧美日韩精品二区 | 丰满少妇一区二区三区专区 | 亚洲热热 | 欧美亚洲一区 | 3d动漫啪啪精品一区二区中文字幕 | 黄色视屏在线看 | 少妇性l交大片免费观看 | 秋霞欧美一区二区三区视频免费 | 精品国产乱码久久久久久浪潮 | 欧美乱论| 欧美精品一区二区成人 | 国产精品亚洲一区二区三区 | 91九色在线视频 | 九九精品网 | 最近中文在线观看 | 大又大粗又爽又黄少妇毛片 | 国产精品91一区二区 | 婷婷激情五月网 | 日韩少妇裸体做爰视频 | 欧美一区二区区 | 国产一级二级三级视频 |