主頁 > .NET開發 > 淺談.NET中的反射

淺談.NET中的反射

2020-09-21 15:41:38 .NET開發

一、概述 

1、通過反射可以提供型別資訊,從而使得我們開發人員在運行時能夠利用這些資訊構造和使用物件

2、反射機制允許程式在執行程序中動態地添加各種功能

二、運行時型別標識

1、運行時型別標志(RTTI),可以在程式執行期間判斷物件型別,例如使用他能夠確切的知道基類參考指向了什么型別物件,

2、運行時型別標識,能預先測驗某個強制型別轉換操作,能否成功,從而避免無效的強制型別轉換例外,

3、在C#中有三個支持RTTI的關鍵字:is、as、typeof,下面一次介紹他們

is運算子:

通過is運算子,能夠判斷物件型別是否為特定型別,如果兩種型別時相同型別,或者兩者之間存在參考,裝箱拆箱轉換,則表明兩種型別時兼容的,代碼如下:

 1         static void Main()
 2         {
 3             A a = new A();
 4             B b = new B();
 5             if (a is A)
 6             {
 7                 Console.WriteLine("a is an A");
 8             }
 9 
10             if (b is A)
11             {
12                 Console.WriteLine("b is an A because it is derived from");
13             }
14 
15             if (a is B)
16             {
17                 Console.WriteLine("This won't display,because a not derived from B");
18             }
19 
20             if (a is object)
21             {
22                 Console.WriteLine("a is an object");
23             }
24             Console.ReadKey();
25         }

結果:

 

 as運算子:

在運行期間執行型別轉換,并且能夠是的型別轉換失敗不拋出例外,而回傳一個null值,其實as也可以看作一個is運算子的簡化備選方式,如下:

 

 1         static void Main()
 2         {
 3             A a = new A();
 4             B b = new B();
 5             if (a is B)
 6             {
 7                 b = (B) a;//由于a變數不是B型別,因此這里將a變數轉換為B型別時無效的
 8             }
 9             else
10             {
11                 b = null;
12             }
13 
14             if (b==null)
15             {
16                 Console.WriteLine("The cast in b=(B)a is not allowed");
17             }
18             //上面使用as運算子,能夠把兩部分合二為一
19             b = a as B;//as運算子先檢查將之轉換型別的有效性,如果有效,則執行強型別轉換程序,這些都在這一句話完成
20             if (b==null)
21             {
22                 Console.WriteLine("The cast in b=(B)a is not allowed");
23             }
24             Console.ReadKey();
25         }

結果:

 

 typeof運算子:

as、is 能夠測驗兩種型別的兼容性,但大多數情況下,還需要獲得某個型別的具體資訊,這就用到了typeof,他可以回傳與具體型別相關的System.Type物件,通過System.Type物件可以去定此型別的特征,一旦獲得給定型別的Type物件,就可以通過使用物件定義的各自屬性、欄位、方法來獲取型別的具體資訊,Type類包含了很多成元,在接下來的反射中再詳細討論,下面簡單的演示Type物件,呼叫它的三個屬性,

 

 1         static void Main()
 2         {
 3             Type t = typeof(StringBuilder);
 4             Console.WriteLine(t.FullName);//FullName屬性回傳型別的全稱
 5             if (t.IsClass)
 6             {
 7                 Console.WriteLine("is a Class");
 8             }
 9 
10             if (t.IsSealed)
11             {
12                 Console.WriteLine("is Sealed");
13             }
14             Console.ReadKey();
15         }

結果:

 

 

三、反射的核心型別:System.Type類

1、許多支持反射的型別都位于System.Reflection命名空間中,他們是.net Reflection API的一部分,所以再使用的反射的程式中一般都是要使用System.Reflection的命名空間,

2、System.Type類包裝了型別,因此是整個反射子系統的核心,這個類中包含了很多屬性和方法,使用這些屬性和方法可以再運行時得到型別的資訊,

3、Type類派生于System.Reflection.MemberInfo抽象類

MemberInfo類中的只讀屬性

屬性

描述

Type DeclaringType

獲取宣告該成員的類或介面的型別

MemberTypes  MemberType

獲取成員的型別,這個值用于指示該成員是欄位、方法、屬性、事件、或建構式

Int MetadataToken

獲取與特定元資料相關的值

Module Module

獲取一個代表反射型別所在模塊(可執行檔案)的Module物件

String  Name

成員的名稱

Type  ReflectedType

反射的物件型別

請注意:

1、MemberType屬性的回傳型別為MemberTypes,這是一個列舉,它定義了用于表示不同成元的資訊值,這些包括:MemberTypes.Constructor、MemeberTypes.Method、MemberTypes.Event、MemberTypes.Property,因此可以通過檢查MemberType屬性來確定成元的型別,例如在MenberType屬性的值為MemberTypes.Method時,該成員為方法

2、MemberInfo類還包含兩個與特性相關的抽象方法:

(1)GetCustomAttributes():獲得與主調物件相關的自定義特性串列,

(2)IsDefined():確定是否為主調物件定義了相應的特性,

(3)GetCustomeAttributesData():回傳有關自定義特性的資訊(特性稍后便會提到)

當然除了MemberInfo類定義的方法和屬性外,Type類自己也添加了許多屬性和方法:如下表(只列出一些常用的,太多二零,自己可以轉定義Type類看一下)

Type類定義的方法

方法

功能

ConstructorInfo[]  GetConstructors()

獲取指定型別的建構式串列

EventInfo[]   GetEvents();

獲取指定型別的時間列

FieldInfo[]   GetFields();

獲取指定型別的欄位列

Type[]   GetGenericArguments();

獲取與已構造的泛型型別系結的型別引數串列,如果指定型別的泛型型別定義,則獲得型別形參,對于正早構造的型別,該串列就可能同時包含型別實參和型別形參

MemberInfo[]   GetMembers();

獲取指定型別的成員串列

MethodInfo[]   GetMethods();

獲取指定型別的方法串列

PropertyInfo[]   GetProperties();

獲取指定型別的屬性串列

下面列出Type型別定義的常用只讀屬性

Type類定義的屬性

屬性

功能

 Assembly   Assembly 

獲取指定型別的程式集

TypeAttributes   Attributes

獲取制定型別的特性

Type   BaseType

獲取指定型別的直接基型別

String  FullName

獲取指定型別的全名

bool   IsAbstract

如果指定型別是抽象型別,回傳true

bool   IsClass

如果指定型別是類,回傳true

string   Namespace

獲取指定型別的命名空間

四、使用反射

上面將的這些,都是為了使用反射做鋪墊的,

通過使用Type類定義的方法和屬性,我們能夠在運行時獲得型別的各種具體資訊,這是一個非常強大的功能,我們一旦得到型別資訊,就可以呼叫其建構式、方法、屬性,可見,反射是允許使用編譯時不可用的代碼的,

由于Feflection API非常多,這里不可能完整的介紹他們(這里如果完整的介紹,據說要一本書,厚書),但是Reflection API是按照一定邏輯設計的,因此,只要知道部分介面的使用方法,就可以舉一反三的使用剩余的介面,

這里我列出四種關鍵的反射技術:

1、獲取方法的資訊

2、呼叫方法

3、構造物件

4、從程式集中加載型別

五、獲取方法的相關資訊

一旦有了Type物件就可以使用GetMethodInfo()方法獲取此型別支持的所有方法串列,該方法回傳一個MethodInfo物件陣列,MethodInfo物件表述了主調型別所支持的方法,它位于System.Reflection命名空間中,MethodInfo類派生于MethodBase抽象類,而MethodBase類繼承了MemberInfo類,因此,我們能夠使用這三各類定義的屬性和方法,例如,使用Name屬性的到方法名,這里有兩個重要的成員:

1、ReturnType屬性:為Type型別的物件,能夠提供方法的回傳型別資訊,

2、GetParameters()方法:回傳引數串列,引數資訊以陣列的形式保存在PatameterInfo物件中,PatameterInfo類定義了大量表述引數資訊的屬性和方法,這里也累出兩個常用的屬性:Name(包含引數名稱資訊的字串),ParameterType(引數型別的資訊),

下面代碼我將使用反射獲得類中的所支持的方法,還有方法的資訊:

 

 1     class Program
 2     {
 3         static void Main()
 4         {
 5             //獲取描述MyClass型別的Type物件
 6             Type t = typeof(MyClass);
 7             Console.WriteLine($"Analyzing methods in {t.Name}");
 8             //MethodInfo物件在System.Reflection命名空間下
 9             MethodInfo[] mi = t.GetMethods();
10             foreach (var methodInfo in mi)
11             {
12                 //回傳方法的回傳型別
13                 Console.Write(methodInfo.ReturnType.Name);
14                 //回傳方法的名稱
15                 Console.Write($" {methodInfo.Name} (");
16                 //獲取方法闡述串列并保存在ParameterInfo物件組中
17                 ParameterInfo[] pi = methodInfo.GetParameters();
18                 for (int i = 0; i < pi.Length; i++)
19                 {
20                     //方法的引數型別名稱
21                     Console.Write(pi[i].ParameterType.Name);
22                     //方法的引數名
23                     Console.Write($" {pi[i].Name}");
24                     if (i+1<pi.Length)
25                     {
26                         Console.Write(", ");
27                     }
28                 }
29 
30                 Console.Write(")");
31                 Console.Write("\r\n");
32                 Console.WriteLine("--------------------------");
33             }
34             Console.ReadKey();
35         }
36     }
37 
38     class MyClass
39     {
40         private int x;
41         private int y;
42 
43         public MyClass()
44         {
45             x = 1;
46             y = 1;
47         }
48 
49         public int Sum()
50         {
51             return x + y;
52         }
53 
54         public bool IsBetween(int i)
55         {
56             if (x < i && i < y)
57             {
58                 return true;
59             }
60 
61             return false;
62         }
63 
64         public void Set(int a, int b)
65         {
66             x = a;
67             y = b;
68         }
69 
70         public void Set(double a, double b)
71         {
72             x = (int)a;
73             y = (int)b;
74         }
75 
76         public void Show()
77         {
78             System.Console.WriteLine($"x:{x},y:{y}");
79         }
80     }

輸出結果:

 

 注意:這里輸出的除了MyClass類定義的所有方法外,也會顯示object類定義的共有非靜態方法,這是因為C#中的所有型別都繼承于Object類,另外,這些資訊是在程式運行時動態獲得的,并不需要知道MyClass類的定義

GetMethods()方法的另一種形式

這種形式可以指定各種標記,已篩選想要獲取的方法,他的通用形式為:MethodInfo[] GetMethods(BindingFlags bindingAttr)

BindingFlags是一個列舉,列舉值有(很多,這里只列出5個常用的吧)

(1)DeclareOnly:僅獲取指定類定義的方法,而不獲取所繼承的方法

(2)Instance:獲取實體方法

(3)NonPublic:獲取非公有方法

(4)Public:獲取共有方法

(5)Static:獲取靜態方法

GetMethods(BindingFlags bindingAttr)這個方法,引數可以使用 or 把兩個或更多標記連接在一起,實際上至少要有Instance(或 Static)與Public(或 NonPublic)標記,否則將不會獲取任何方法,下我們就寫一個示例來演示一下,

 1     class Program
 2     {
 3         static void Main()
 4         {
 5             //獲取描述MyClass型別的Type物件
 6             Type t = typeof(MyClass);
 7             Console.WriteLine($"Analyzing methods in {t.Name}");
 8             //MethodInfo物件在System.Reflection命名空間下
 9             //不獲取繼承方法,為實體方法,·為公用的
10             MethodInfo[] mi = t.GetMethods(BindingFlags.DeclaredOnly|BindingFlags.Instance|BindingFlags.Public);
11             foreach (var methodInfo in mi)
12             {
13                 //回傳方法的回傳型別
14                 Console.Write(methodInfo.ReturnType.Name);
15                 //回傳方法的名稱
16                 Console.Write($" {methodInfo.Name} (");
17                 //獲取方法闡述串列并保存在ParameterInfo物件組中
18                 ParameterInfo[] pi = methodInfo.GetParameters();
19                 for (int i = 0; i < pi.Length; i++)
20                 {
21                     //方法的引數型別名稱
22                     Console.Write(pi[i].ParameterType.Name);
23                     //方法的引數名
24                     Console.Write($" {pi[i].Name}");
25                     if (i+1<pi.Length)
26                     {
27                         Console.Write(", ");
28                     }
29                 }
30 
31                 Console.Write(")");
32                 Console.Write("\r\n");
33                 Console.WriteLine("--------------------------");
34             }
35             Console.ReadKey();
36         }
37     }
38 
39     class MyClass
40     {
41         private int x;
42         private int y;
43 
44         public MyClass()
45         {
46             x = 1;
47             y = 1;
48         }
49 
50         public int Sum()
51         {
52             return x + y;
53         }
54 
55         public bool IsBetween(int i)
56         {
57             if (x < i && i < y)
58             {
59                 return true;
60             }
61 
62             return false;
63         }
64 
65         public void Set(int a, int b)
66         {
67             x = a;
68             y = b;
69         }
70 
71         public void Set(double a, double b)
72         {
73             x = (int)a;
74             y = (int)b;
75         }
76 
77         public void Show()
78         {
79             System.Console.WriteLine($"x:{x},y:{y}");
80         }
81     }

輸出結果:

 

上面例子可以看出,只顯示了MyClass類顯示定義的方法,private int Sum() 也不顯示了 

六、使用反射呼叫方法

上面我們通過反射獲取到了類中的所有資訊,下面我們就再使用反射呼叫反射獲取到的方法,要呼叫反射獲取到的方法,則需要在MethodInfo實體上呼叫Invoke()方法,Invoke()的使用,在下面例子中演示說明:

下面例子是先通過反射獲取到要呼叫的方法,然后使用Invoke()方法,呼叫獲取到的指定方法:

 

 1     class Program
 2     {
 3         static void Main()
 4         {
 5             //獲取描述MyClass型別的Type物件
 6             Type t = typeof(MyClass);
 7             MyClass reflectObj = new MyClass();
 8             reflectObj.Show();
 9             //不獲取繼承方法,為實體方法,·為公用的
10             MethodInfo[] mi = t.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public);
11             foreach (var methodInfo in mi)
12             {
13 
14                 //獲取方法闡述串列并保存在ParameterInfo物件組中
15                 ParameterInfo[] pi = methodInfo.GetParameters();
16                 if (methodInfo.Name.Equals("Set", StringComparison.Ordinal) && pi[0].ParameterType == typeof(int))
17                 {
18                     object[] args = new object[2];
19                     args[0] = 9;
20                     args[1] = 10;
21                     methodInfo.Invoke(reflectObj,args);
22                 }
23             }
24             Console.ReadKey();
25         }
26     }
27 
28     class MyClass
29     {
30         private int x;
31         private int y;
32 
33         public MyClass()
34         {
35             x = 1;
36             y = 1;
37         }
38 
39         public int Sum()
40         {
41             return x + y;
42         }
43 
44         public bool IsBetween(int i)
45         {
46             if (x < i && i < y)
47             {
48                 return true;
49             }
50 
51             return false;
52         }
53 
54         public void Set(int a, int b)
55         {
56             x = a;
57             y = b;
58             Show();
59         }
60 
61         private void Set(double a, double b)
62         {
63             x = (int)a;
64             y = (int)b;
65         }
66 
67         public void Show()
68         {
69             System.Console.WriteLine($"x:{x},y:{y}");
70         }
71     }

獲取Type物件的建構式

這個之前的闡述中,由于MyClass型別的物件都是顯示創建的,因此使用反射技術呼叫MyClass類中的方法是沒有任何優勢的,還不如以普通方式呼叫方便簡單呢,但是,如果物件是在運行時動態創建的,反射功能的優勢就會顯現出來,在這種情況下,要先獲取一個建構式串列,然后呼叫串列中的某個建構式,創建一個該型別的實體,通過這種機制,可以在運行時實體化任意型別的物件,而不必在宣告陳述句中指定型別,

示例代碼如下:

 

 1     class Program
 2     {
 3         static void Main()
 4         {
 5             //獲取描述MyClass型別的Type物件
 6             Type t = typeof(MyClass);
 7             int val;
 8             //使用這個方法獲取建構式串列
 9             ConstructorInfo[] ci = t.GetConstructors();
10             int x;
11             for (x = 0; x < ci.Length; x++)
12             {
13                 //獲取當構造引數串列
14                 ParameterInfo[] pi = ci[x].GetParameters();
15                 if (pi.Length == 2)
16                 {
17                     //如果當前建構式有2個引數,則跳出回圈
18                     break;
19                 }
20             }
21 
22             if (x == ci.Length)
23             {
24                 return;
25             }
26             object[] consArgs = new object[2];
27             consArgs[0] = 10;
28             consArgs[1] = 20;
29             //實體化一個這個建構式有連個引數的型別物件,如果引數為空,則為null
30 
31             object reflectOb = ci[x].Invoke(consArgs);
32 
33             MethodInfo[] mi = t.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public);
34             foreach (var methodInfo in mi)
35             {
36                 if (methodInfo.Name.Equals("Sum", StringComparison.Ordinal))
37                 {
38                     val = (int)methodInfo.Invoke(reflectOb, null);
39                     Console.WriteLine($"Sum is {val}");
40                 }
41             }
42             Console.ReadKey();
43         }
44     }
45 
46     class MyClass
47     {
48         private int x;
49         private int y;
50 
51         public MyClass(int i)
52         {
53             x = y + i;
54         }
55 
56         public MyClass(int i, int j)
57         {
58             x = i;
59             y = j;
60         }
61 
62         public int Sum()
63         {
64             return x + y;
65         }
66     }

輸出結果:

 

 七、從程式集獲得型別

在這之前的闡述中可以看出一個型別的所有資訊都能夠通過反射得到,但是MyClass型別本身,我們卻沒有做到獲取,雖然前面的闡述實體,可以動態確定MyClass類的資訊,但是他們都是基于以下事實:預先知道型別名稱,并且在typeof與劇中使用它獲得Type物件,盡管這種方式可能在很多情況下都管用,但是要發揮反射的全部功能,我們還需要分析反射程式集的內容來動態確定程式的可用型別,

借助Reflection API,可以加載程式集,獲取它的相關資訊并創建其公共可用型別的實體,通過這種機制,程式能夠搜索其環境,利用潛在的功能,而無需再編譯期間顯示的定義他們,這是一個非常有效且令人興奮的概念,為了說明如何獲取程式集中的型別,我創建了兩個檔案,第一個檔案定義一組類,第二個檔案則反射各個型別的資訊,代碼效果如下:

1、這下面代碼編譯生成MyTest2_C.exe檔案

 1     class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             Console.WriteLine("Hello word !");
 6             Console.ReadKey();
 7         }
 8     }
 9 
10     class MyClass
11     {
12         private int x;
13         private int y;
14 
15         public MyClass(int i)
16         {
17             x = y + i;
18         }
19 
20         public MyClass(int i, int j)
21         {
22             x = i;
23             y = j;
24         }
25 
26         public int Sum()
27         {
28             return x + y;
29         }
30     }

2、這下面的代碼時獲取上面生成程式集的

 1     class Program
 2     {
 3         static void Main()
 4         {
 5             //加載指定的程式集
 6             Assembly asm = Assembly.LoadFrom(@"E:\自己的\MyTest\MyTest2_C\bin\Debug\MyTest2_C.exe");
 7             //獲取程式集中的所有型別串列
 8             Type[] allType = asm.GetTypes();
 9             foreach (var type in allType)
10             {
11                 //列印出型別名稱
12                 Console.WriteLine(type.Name);
13             }
14 
15             Console.ReadKey();
16         }
17     }

輸出結果:

 

 上面獲取到了程式集中的型別,如果像操作程式集型別中的方法,則跟前面我們表述的方法一樣操作即可,

好了,.Net反射我們就介紹到這里啦~

轉載請註明出處,本文鏈接:https://www.uj5u.com/net/97988.html

標籤:C#

上一篇:C# detect latest .net framework installed on PC

下一篇:C#面向物件--命名空間

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • WebAPI簡介

    Web體系結構: 有三個核心:資源(resource),URL(統一資源識別符號)和表示 他們的關系是這樣的:一個資源由一個URL進行標識,HTTP客戶端使用URL定位資源,表示是從資源回傳資料,媒體型別是資源回傳的資料格式。 接下來我們說下HTTP. HTTP協議的系統是一種無狀態的方式,使用請求/ ......

    uj5u.com 2020-09-09 22:07:47 more
  • asp.net core 3.1 入口:Program.cs中的Main函式

    本文分析Program.cs 中Main()函式中代碼的運行順序分析asp.net core程式的啟動,重點不是剖析原始碼,而是理清程式開始時執行的順序。到呼叫了哪些實體,哪些法方。asp.net core 3.1 的程式入口在專案Program.cs檔案里,如下。ususing System; us ......

    uj5u.com 2020-09-09 22:07:49 more
  • asp.net網站作為websocket服務端的應用該如何寫

    最近被websocket的一個問題困擾了很久,有一個需求是在web網站中搭建websocket服務。客戶端通過網頁與服務器建立連接,然后服務器根據ip給客戶端網頁發送資訊。 其實,這個需求并不難,只是剛開始對websocket的內容不太了解。上網搜索了一下,有通過asp.net core 實作的、有 ......

    uj5u.com 2020-09-09 22:08:02 more
  • ASP.NET 開源匯入匯出庫Magicodes.IE Docker中使用

    Magicodes.IE在Docker中使用 更新歷史 2019.02.13 【Nuget】版本更新到2.0.2 【匯入】修復單列匯入的Bug,單元測驗“OneColumnImporter_Test”。問題見(https://github.com/dotnetcore/Magicodes.IE/is ......

    uj5u.com 2020-09-09 22:08:05 more
  • 在webform中使用ajax

    如果你用過Asp.net webform, 說明你也算是.NET 開發的老兵了。WEBform應該是2011 2013左右,當時還用visual studio 2005、 visual studio 2008。后來基本都用的是MVC。 如果是新開發的專案,估計沒人會用webform技術。但是有些舊版 ......

    uj5u.com 2020-09-09 22:08:50 more
  • iis添加asp.net網站,訪問提示:由于擴展配置問題而無法提供您請求的

    今天在iis服務器配置asp.net網站,遇到一個問題,記錄一下: 問題:由于擴展配置問題而無法提供您請求的頁面。如果該頁面是腳本,請添加處理程式。如果應下載檔案,請添加 MIME 映射。 WindowServer2012服務器,添加角色安裝完.netframework和iis之后,運行aspx頁面 ......

    uj5u.com 2020-09-09 22:10:00 more
  • WebAPI-處理架構

    帶著問題去思考,大家好! 問題1:HTTP請求和回傳相應的HTTP回應資訊之間發生了什么? 1:首先是最底層,托管層,位于WebAPI和底層HTTP堆疊之間 2:其次是 訊息處理程式管道層,這里比如日志和快取。OWIN的參考是將訊息處理程式管道的一些功能下移到堆疊下端的OWIN中間件了。 3:控制器處理 ......

    uj5u.com 2020-09-09 22:11:13 more
  • 微信門戶開發框架-使用指導說明書

    微信門戶應用管理系統,采用基于 MVC + Bootstrap + Ajax + Enterprise Library的技術路線,界面層采用Boostrap + Metronic組合的前端框架,資料訪問層支持Oracle、SQLServer、MySQL、PostgreSQL等資料庫。框架以MVC5,... ......

    uj5u.com 2020-09-09 22:15:18 more
  • WebAPI-HTTP編程模型

    帶著問題去思考,大家好!它是什么?它包含什么?它能干什么? 訊息 HTTP編程模型的核心就是訊息抽象,表示為:HttPRequestMessage,HttpResponseMessage.用于客戶端和服務端之間交換請求和回應訊息。 HttpMethod類包含了一組靜態屬性: private stat ......

    uj5u.com 2020-09-09 22:15:23 more
  • 部署WebApi隨筆

    一、跨域 NuGet參考Microsoft.AspNet.WebApi.Cors WebApiConfig.cs中配置: // Web API 配置和服務 config.EnableCors(new EnableCorsAttribute("*", "*", "*")); 二、清除默認回傳XML格式 ......

    uj5u.com 2020-09-09 22:15:48 more
最新发布
  • C#多執行緒學習(二) 如何操縱一個執行緒

    <a href="https://www.cnblogs.com/x-zhi/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2943582/20220801082530.png" alt="" /></...

    uj5u.com 2023-04-19 09:17:20 more
  • C#多執行緒學習(二) 如何操縱一個執行緒

    C#多執行緒學習(二) 如何操縱一個執行緒 執行緒學習第一篇:C#多執行緒學習(一) 多執行緒的相關概念 下面我們就動手來創建一個執行緒,使用Thread類創建執行緒時,只需提供執行緒入口即可。(執行緒入口使程式知道該讓這個執行緒干什么事) 在C#中,執行緒入口是通過ThreadStart代理(delegate)來提供的 ......

    uj5u.com 2023-04-19 09:16:49 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    <a href="https://www.cnblogs.com/huangxincheng/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/214741/20200614104537.png" alt="" /&g...

    uj5u.com 2023-04-18 08:39:04 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    一:背景 1. 講故事 前段時間協助訓練營里的一位朋友分析了一個程式卡死的問題,回過頭來看這個案例比較經典,這篇稍微整理一下供后來者少踩坑吧。 二:WinDbg 分析 1. 為什么會卡死 因為是表單程式,理所當然就是看主執行緒此時正在做什么? 可以用 ~0s ; k 看一下便知。 0:000> k # ......

    uj5u.com 2023-04-18 08:33:10 more
  • SignalR, No Connection with that ID,IIS

    <a href="https://www.cnblogs.com/smartstar/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/u36196.jpg" alt="" /></a>...

    uj5u.com 2023-03-30 17:21:52 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:15:33 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:13:31 more
  • C#遍歷指定檔案夾中所有檔案的3種方法

    <a href="https://www.cnblogs.com/xbhp/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/957602/20230310105611.png" alt="" /></a&...

    uj5u.com 2023-03-27 14:46:55 more
  • C#/VB.NET:如何將PDF轉為PDF/A

    <a href="https://www.cnblogs.com/Carina-baby/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2859233/20220427162558.png" alt="" />...

    uj5u.com 2023-03-27 14:46:35 more
  • 武裝你的WEBAPI-OData聚合查詢

    <a href="https://www.cnblogs.com/podolski/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/616093/20140323000327.png" alt="" /><...

    uj5u.com 2023-03-27 14:46:16 more