第六节:反射(几种写法、好处和弊端、利用反射实现IOC)

一. 加载dll,读取相关信息

1. 加载程序集的三种方式

 调用Assembly类下的三个方法:Load、LoadFile、LoadFrom。

复制代码

1        //1.1 Load方法:动态默认加载当前路径下的(bin)下的dll文件,不需要后缀
2             Assembly assembly = Assembly.Load("DB.SQLServer");
3             //1.2 LoadFile方法:程序集的绝对路径
4             Assembly assembly2 = Assembly.LoadFile(@"D:\我的框架之路\DotNet体系\02-DotNet进阶\02-反射\01-code\Reflection\bin\Debug\DB.SQLServer.dll");
5             //1.3 LoadFrom方法:可以是当前路径(需要写上后缀.dll),也可以是绝对路径
6             Assembly assembly3 = Assembly.LoadFrom("DB.SQLServer.dll");

复制代码

2. 获取程序集中所有的类

 通过方法GetTypes来实现。

1 Assembly assembly = Assembly.Load("DB.SQLServer");
2 Type[] t1 = assembly.GetTypes();

    通过方法GetType("类名全写")来实现获取单个类(DBHelper)。

1 Type tItem = assembly.GetType("DB.SQLServer.DBHelper");

3. 获取类中的所有构造函数

  通过方法GetConstructors来实现。

1 //1.加载程序集
2 Assembly assembly = Assembly.Load("DB.SQLServer");
3 //2.获取程序集中的特定类
4 Type tItem = assembly.GetType("DB.SQLServer.DBHelper");
5 //3.获取特定类中的所有构造函数
6 ConstructorInfo[] cInfor = tItem.GetConstructors();

4. 获取类中的所有属性

  通过方法GetProperties来实现。

1  //1.加载程序集
2 Assembly assembly = Assembly.Load("DB.SQLServer");
3 //2.获取程序集中的特定类
4 Type tItem = assembly.GetType("DB.SQLServer.DBHelper");
5 //3.获取特定类中的所有属性
6 PropertyInfo[] propertyInfo = tItem.GetProperties();

5. 获取类中的所有方法

   通过方法GetMethods来实现。

 //1.加载程序集
Assembly assembly = Assembly.Load("DB.SQLServer");
//2.获取程序集中的特定类
Type tItem = assembly.GetType("DB.SQLServer.DBHelper");
//3.获取特定类中的所有方法
MethodInfo[] methordInfo = tItem.GetMethods();

6. 获取类中的所有接口

  通过方法GetInterfaces来实现。

1 //1.加载程序集
2 Assembly assembly = Assembly.Load("DB.SQLServer");
3 //2.获取程序集中的特定类
4 Type tItem = assembly.GetType("DB.SQLServer.DBHelper");
5 //3.获取特定类中的所有接口
6 Type[] type = tItem.GetInterfaces();

二. 反射创建对象

1. 反射创建对象

 通过Activator.CreateInstance()方法来创建对象

1.1 ReflectionTest类的代码

复制代码

 1  public class ReflectionTest2     {3         public int Id { get; set; }4         public string Name { get; set; }5 6         public string Field = null;7         public static string FieldStatic = null;8 9 
10         #region 构造函数
11         public ReflectionTest()
12         {
13             Console.WriteLine("这里是{0}无参数构造函数", this.GetType());
14         }
15 
16         public ReflectionTest(string name)
17         {
18             Console.WriteLine("这里是{0} 有1个参数构造函数", this.GetType());
19         }
20 
21         public ReflectionTest(int id, string name)
22         {
23             Console.WriteLine("这里是{0} 有2个参数构造函数", this.GetType());
24         }
25         #endregion
26 
27         public void Show1()
28         {
29             Console.WriteLine("这里是{0}的Show1", this.GetType());
30         }
31 
32         public void Show2(int id)
33         {
34 
35             Console.WriteLine("这里是{0}的Show2", this.GetType());
36         }
37 
38         public static void ShowStatic(string name)
39         {
40             Console.WriteLine("这里是{0}的ShowStatic", typeof(ReflectionTest));
41         }
42 
43         public void Show3()
44         {
45             Console.WriteLine("这里是{0}的Show3_1", this.GetType());
46         }
47 
48         public void Show3(int id, string name)
49         {
50             Console.WriteLine("这里是{0}的Show3", this.GetType());
51         }
52 
53         public void Show3(string name, int id)
54         {
55             Console.WriteLine("这里是{0}的Show3_2", this.GetType());
56         }
57 
58         public void Show3(int id)
59         {
60 
61             Console.WriteLine("这里是{0}的Show3_3", this.GetType());
62         }
63 
64         public void Show3(string name)
65         {
66 
67             Console.WriteLine("这里是{0}的Show3_4", this.GetType());
68         }
69 
70         private void Show4(string name)
71         {
72             Console.WriteLine("这里是{0}的Show4", this.GetType());
73         }
74         public void ShowGeneric<T>(T name)
75         {
76             Console.WriteLine("这里是{0}的ShowStatic  T={1}", this.GetType(), typeof(T));
77         }
78     }

复制代码

1.2 反射创建对象的代码

复制代码

 1 //1.加载程序集2 Assembly assembly = Assembly.Load("DB.SQLServer");3 //2.获取程序集中的特定类4 Type tItem = assembly.GetType("DB.SQLServer.ReflectionTest");5  //3.1 无参构造函数6 Activator.CreateInstance(tItem);7  //3.2 一个参数的构造函数8 Activator.CreateInstance(tItem ,"1");9 //3.3 两个参数的构造函数
10  Activator.CreateInstance(tItem , 1,"2");

复制代码

2. 反射破坏单例,调用私有构造函数

   单例代码

复制代码

 1  public sealed class Singleton2     {3         private Singleton()4         {5             Console.WriteLine("初始化一次");6         }7 8         private static Singleton Instance = new Singleton();9 
10         public static Singleton CreateInstance()
11         {
12             return Instance;
13         }
14     }

复制代码

   破坏单例,调用私有构造函数代码

1 //1.加载程序集
2 Assembly assembly = Assembly.Load("DB.SQLServer");
3 //2. 获取单例类
4 Type tc3 = assembly .GetType("DB.SQLServer.Singleton");
5 //3. 创建对象
6 Activator.CreateInstance(tc3, true);

3. 反射创建泛型(扩展)

1  //1.加载程序集
2 Assembly assembly = Assembly.Load("DB.SQLServer");
3  //2. 获取单例类
4 Type tc4 = assembly4.GetType("DB.SQLServer.GenericClass`1");
5 tc4 = tc4.MakeGenericType(typeof(int));
6 Activator.CreateInstance(tc4);

三. IOC(反射+简单工厂+配置文件)

   背景:有三套相同的数据库,分别是SQLServer、MySQL、Oracle数据库,要求可以分别连接这三个不同的数据库,并且发布后,可以在不重新发布的情况下,切换连接数据库。

   对应上述背景,建立相应的解决方案,目录如下,并介绍介绍几种传统的解决方案

方案一:在Reflection中直接添加对DB.SQLServer的引用

1  Console.WriteLine("------------------------------------1. 传统方式调用DBHelper中的Query方法--------------------------------------");
2  //1.传统的方式调用(需要对 DB.SQLServer添加引用)
3  DBHelper db1 = new DBHelper("123");
4  db1.Query();

方案二:在Reflection中直接添加对DB.SQLServer、DB.Interface的引用

1   Console.WriteLine("------------------------------------2. 接口的方式调用--------------------------------------");
2   //2. 接口的方式调用(只需要引用接口的程序集即可)
3   IDBHelper idb1 = new DBHelper("123");
4   idb1.Query();

点评:以上两种方案实质上都是通过对相应的实现类添加引用,new出来对象,然后调用方法来实现,没法发布后动态修改数据库。

 方案三:通过反射来创建对象,只需要添加对DB.Interface的引用即可,但需要把DB.SQLServer、DB.MySQL、DB.Oracle的生成dll的目录改成Reflection程序下

复制代码

1  Console.WriteLine("------------------------------------3. 反射的方式创建对象--------------------------------------");
2  //3. 反射的方式创建对象(不需要直接添加对其引用,只需要把相应的程序生成路径改成Reflection中即可)
3  Assembly assembly4 = Assembly.Load("DB.SQLServer");
4  Type tc = assembly4.GetType("DB.SQLServer.DBHelper");
5  //object myDbHelper = Activator.CreateInstance(tc, "123"); //调用带参数的构造函数
6  object myDbHelper = Activator.CreateInstance(tc);     //默认调用无参构造函数
7  IDBHelper idb2 = (IDBHelper)myDbHelper;
8  idb2.Query();

复制代码

点评:该方案只需要对接口添加引用,符合了面向接口编程的思想,但是发布后在不修改代码的情况下,不能切换数据库。

方案四:IOC(反射+简单工厂+配置文件),需要添加对DB.Interface的引用,并且把DB.SQLServer、DB.MySQL、DB.Oracle的生成dll的目录改成Reflection程序下

配置文件:

复制代码

 1   <appSettings>2     <!--直接修改配置文件,可以修改数据库连接牛逼,可以直接切换 oracle 、mysql数据库,发布后可以直接通过改配置文件,切换数据库,代码什么也不用改,体会:反射+面向接口编程-->3     <!--前提:相应的DBHelper类必须满足接口约束,需要把Oracle或MySql的dll文件拷贝到Reflection中的bin文件中  -->4     <!--SQLServer改为:         -->5     <!--<add key="IDBHelper-dllName" value="DB.SQLServer"/>6     <add key="IDBHelper-className" value="DB.SQLServer.DBHelper"/>-->7     <!--Oracle改为:         -->8     <!--<add key="IDBHelper-dllName" value="DB.Oracle"/>9     <add key="IDBHelper-className" value="DB.Oracle.DBHelper"/>-->
10     <!--MySql改为:         -->
11     <add key="IDBHelper-dllName" value="DB.MySql"/>
12     <add key="IDBHelper-className" value="DB.MySql.DBHelper"/>
13   </appSettings>

复制代码

简单工厂:

复制代码

 1 /// <summary>2     /// 简单工厂,创建对象3     /// </summary>4     public class SimpleFactory5     {6         private static string IDBHelperdllName = ConfigurationManager.AppSettings["IDBHelper-dllName"];7         private static string IDBHelperClassName = ConfigurationManager.AppSettings["IDBHelper-className"];8 9         public static IDBHelper CreateDBHelper()
10         {
11             Assembly assembly = Assembly.Load(IDBHelperdllName);
12             Type type = assembly.GetType(IDBHelperClassName);
13             object obj = Activator.CreateInstance(type);
14             return (IDBHelper)obj;
15         }
16 
17     }

复制代码

调用:

1   Console.WriteLine("------------------------------------4. IOC(反射+简单工厂+配置文件)--------------------------------------");
2   //4. IOC(反射+简单工厂+配置文件)(不需要直接添加对其引用,只需要把相应的程序生成路径改成Reflection中即可)
3   IDBHelper idb3 = SimpleFactory.CreateDBHelper();
4   idb3.Query();

 

 

四. 反射调用实例方法、静态方法、重载方法

复制代码

 1         //2. 实例方法、静态方法、重载方法的调用2             {3                 object obj = Activator.CreateInstance(tc5);4                 Console.WriteLine("---------------------------------2.1 调用无参、有参的实例方法-------------------------------------");5                 //2.1 调用无参、有参的实例方法6                 {7                     MethodInfo methord = tc5.GetMethod("Show1");8                     methord.Invoke(obj, null);9                 }
10                 {
11                     MethodInfo methord = tc5.GetMethod("Show2");
12                     methord.Invoke(obj, new object[]{11});
13                 }
14 
15                 Console.WriteLine("---------------------------------2.2 调用静态方法-------------------------------------");
16                 //2.2 调用静态方法
17                 {
18                     MethodInfo methord = tc5.GetMethod("ShowStatic");
19                     methord.Invoke(obj, new object[] { "ShowStatic1234" });
20                 }
21 
22                 Console.WriteLine("---------------------------------2.3 调用重载方法(需要在创建方法的时候,把类型传进去)-------------------------------------");
23                 //2.3 调用重载方法(需要在创建方法的时候,把类型传进去)
24                 {
25                     MethodInfo methord = tc5.GetMethod("Show3", new Type[] { });
26                     methord.Invoke(obj, null);
27                 }
28                 {
29                     MethodInfo methord = tc5.GetMethod("Show3", new Type[] { typeof(int)});
30                     methord.Invoke(obj, new object[] { 11 });
31                 }
32                 {
33                     MethodInfo methord = tc5.GetMethod("Show3", new Type[] { typeof(string) });
34                     methord.Invoke(obj, new object[] { "11" });
35                 }
36                 {
37                     MethodInfo methord = tc5.GetMethod("Show3", new Type[] { typeof(int), typeof(string) });
38                     methord.Invoke(obj, new object[] { 11 ,"11"});
39                 }
40                 {
41                     MethodInfo methord = tc5.GetMethod("Show3", new Type[] { typeof(string), typeof(int) });
42                     methord.Invoke(obj, new object[] { "11",11 });
43                 }
44 
45                 Console.WriteLine("---------------------------------2.4 调用私有方法-------------------------------------");
46                 //2.4 调用私有方法
47                 {
48                     MethodInfo methord = tc5.GetMethod("Show4", BindingFlags.Instance|BindingFlags.NonPublic);
49                     methord.Invoke(obj, new object[] { "11" });
50                 }
51                 Console.WriteLine("---------------------------------2.5 调用泛型方法-------------------------------------");
52                 //2.5 调用泛型方法
53                 {
54                     MethodInfo methord = tc5.GetMethod("ShowGeneric");
55                     methord = methord.MakeGenericMethod(typeof(string));
56                     methord.Invoke(obj, new object[] { "123" });
57                 }
58 
59             }

复制代码

五. 反射字段和属性,获取值和设置值

复制代码

  {//实例化对象ReflectionTest rTest = new ReflectionTest();//反射Assembly assembly5 = Assembly.Load("DB.SQLServer");Type type5 = assembly5.GetType("DB.SQLServer.ReflectionTest");object object5 = Activator.CreateInstance(type5);//1.获取类的所有属性Console.WriteLine("------------------------------------1.获取类的属性--------------------------------------");var pInfor= type5.GetProperties();foreach (var item in pInfor){Console.WriteLine(item.Name);if (item.Name.Equals("Id")){item.SetValue(object5, 12332);}}Console.WriteLine("------------------------------------输出ID属性值--------------------------------------");rTest = (ReflectionTest)object5;Console.WriteLine(rTest.Id);//2.获取类的字段Console.WriteLine("------------------------------------2.获取类的字段--------------------------------------");foreach (var item in type5.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public)){Console.WriteLine(item.Name);}}

复制代码

六. 反射的好处和局限

复制代码

 1  {2                //反射的好处:3                //反射是.NET中的重要机制,通过反射,可以在运行时获得程序或程序集中每一个类型(包括类、结构、委托、接口和枚举等)的成员和成员的信息。4                //有了反射,即可对每一个类型了如指掌。另外我还可以直接创建对象,即使这个对象的类型在编译时还不知道。5 6                 //性能局限7                 Console.WriteLine("------------------------------测试普通方法和反射的耗时情况--------------------------------------");8                 {9                     //1.普通方法
10                     Stopwatch watch = new Stopwatch();
11                     watch.Start();
12                     for (var i = 0; i < 1000000; i++)
13                     {
14                         DBHelper2 dh = new DBHelper2();
15                         dh.Id = 1;
16                         dh.Name = "maru";
17                         dh.Query();
18                     }
19                     watch.Stop();
20                     Console.WriteLine("普通方式花费{0}ms:",watch.ElapsedMilliseconds);
21                 }
22                 {
23                     //2. 反射的方法
24                     Stopwatch watch = new Stopwatch();
25                     watch.Start();
26                     Assembly assembley6 = Assembly.Load("DB.SQLServer");
27                     Type type6 = assembley6.GetType("DB.SQLServer.DBHelper2");
28                     for (var i = 0; i < 1000000; i++)
29                     {
30                         object obj6 = Activator.CreateInstance(type6);
31                         foreach (var item in type6.GetProperties())
32                         {
33                             if (item.Name.Equals("Id"))
34                             {
35                                 item.SetValue(obj6, 1);
36                             }
37                             if (item.Name.Equals("Name"))
38                             {
39                                 item.SetValue(obj6, "maru");
40                             }
41                         }
42                         MethodInfo m6 = type6.GetMethod("Query");
43                         m6.Invoke(obj6, null);
44                     }
45                     watch.Stop();
46                     Console.WriteLine("反射方式花费{0}ms:", watch.ElapsedMilliseconds);
47                 }
48             }

复制代码

运行结果:

 七. 补充:获取类的属性、方法、特性、构造函数等,设置属性值,获取属性值

函数                                                                         说明
GetConstructor(s)                  取得此类型的创建函数,其将回传一个ConstructorInfo对象或数组
GetField(s)                             取得此类型中成员变量,其将回传一个FiledInfo对象或数组
GetMember(s)                        取得此类中的成员,其类型可以是变量、事件、属性、方法及Nested Type,其将回传一个MemberInfo对象或数组
GetEvent(s)                            取得此类型中的事件,其将回传一个EventInfo对象或数组
GetProperty/GetProperties         取得此类型中的属性,其将回传一个PropertyInfo对象或数组
GetNestedType(s)                  取得声明于此类型内类型,其将回传一个Type对象或数组
GetCustomAttibutes                    取得绑定于此类型的Attitudes
GetValue(t)                                  获取t对象的的属性值
SetValue(t,"XXX")                        设置t对象的属性值为XXX

实体代码:

复制代码

 1  [Description("我是Person类")]2     public class Person3     {4         //1. 构造函数5         public Person()6         {7 8         }9         public Person(string sex)
10         {
11             this._Sex = sex;
12         }
13         //2. 属性
14 
15         [Description("我是id")]
16         public string id { get; set; }
17 
18         [ReadOnly(true)]
19         public string userName { get; set; }
20 
21         public string userPwd { get; set; }
22 
23         //3.成员变量
24 
25         public string _Sex = null;
26 
27         public int _Age;
28 
29         //4. 特性  [Description("我是id")]     [ReadOnly(true)]
30 
31         //5. 方法
32         public string GetOwnSex()
33         {
34             return this._Sex;
35         }
36 
37         //6. 事件
38         public event Action MyEvent;
39 
40 
41 
42     }

复制代码

调用代码:

复制代码

 1  Person person1 = new Person()2                 {3                     id = "123",4                     userName = "ypf",5                     userPwd = "123456",6                 };7                 //获取类8                 Type type = person1.GetType();9                 {
10                     Console.WriteLine("---------------1. 获取构造函数-----------------");
11                     ConstructorInfo[] constructorInfoList = type.GetConstructors();
12                     for (int i = 0; i < constructorInfoList.Length; i++)
13                     {
14                         Console.WriteLine(constructorInfoList[i]);
15                     }
16                 }
17                 {
18                     Console.WriteLine("---------------2. 获取成员变量-----------------");
19                     FieldInfo[] fielInforList = type.GetFields();
20                     for (int i = 0; i < fielInforList.Length; i++)
21                     {
22                         Console.WriteLine(fielInforList[i]);
23                     }
24                 }
25                 {
26                     Console.WriteLine("---------------3. 获取成员-----------------");
27                     MemberInfo[] memberInfoList = type.GetMembers();
28                     for (int i = 0; i < memberInfoList.Length; i++)
29                     {
30                         Console.WriteLine(memberInfoList[i]);
31                     }
32                 }
33                 {
34                     Console.WriteLine("---------------4. 获取事件-----------------");
35                     EventInfo[] eventInfoList = type.GetEvents();
36                     for (int i = 0; i < eventInfoList.Length; i++)
37                     {
38                         Console.WriteLine(eventInfoList[i]);
39                     }
40                 }
41                 {
42                     Console.WriteLine("---------------5. 获取属性-----------------");
43                     PropertyInfo[] propertyInfoList = type.GetProperties();
44                     for (int i = 0; i < propertyInfoList.Length; i++)
45                     {
46                         Console.WriteLine(propertyInfoList[i]);
47                     }
48                 }
49                 {
50                     Console.WriteLine("---------------6. 获取特性-----------------");
51                     //1. 获取属性上的特性
52                     //因为这些测试所用的特性都是加在属性上的,所以要先获取属性
53                     PropertyInfo[] propertyInfoList = type.GetProperties();
54                     foreach (var item in propertyInfoList)
55                     {
56                         //获取该属性上的所有特性
57                         object[] attributeInfoList = item.GetCustomAttributes(true);
58                         foreach (var item2 in attributeInfoList)
59                         {
60                             Console.WriteLine("{0}属性上的特性为{1}", item, item2);
61                         }
62 
63                     }
64                     //2. 获取类上的属性
65                     object[] attributeInfoList2 = type.GetCustomAttributes(true);
66                     foreach (var item3 in attributeInfoList2)
67                     {
68                         Console.WriteLine("{0}类上的特性为{1}", type, item3);
69                     }       
70                 }
71                 {
72                     Console.WriteLine("---------------7. 获取id属性的值-----------------");
73                     PropertyInfo idProperty = type.GetProperty("id");
74                     Console.WriteLine("属性名为:{0}", idProperty.Name);
75                     Console.WriteLine("属性值为:{0}", idProperty.GetValue(person1));
76                     //设置属性值
77                     idProperty.SetValue(person1, "2345");
78                     Console.WriteLine("设置后的属性值为:{0}", idProperty.GetValue(person1));
79 
80                 }

复制代码

结果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/438591.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第七节:语法总结(1)(自动属性、out参数、对象初始化器、var和dynamic等)

一. 语法糖简介 语法糖也译为糖衣语法&#xff0c;是由英国计算机科学家彼得约翰兰达&#xff08;Peter J. Landin&#xff09;发明的一个术语&#xff0c;指计算机语言中添加的某种语法&#xff0c;这种语法对语言的功能并没有影响&#xff0c;但是更方便程序员使用。通常来说…

java不用插件播放媒体文件_java servlet不用插件上传文件:

展开全部import java.net.*;import java.io.*;import java.util.*;import javax.servlet.*;import javax.servlet.http.*;public class SaveFileServlet extends HttpServlet{FileWriter savefile;String filename null;String value null;/*** Handles a POST request*/publ…

第八节:语法总结(2)(匿名类、匿名方法、扩展方法)

一. 匿名类 1. 传统的方式给类赋值&#xff0c;需要先建一个实体类→实例化→赋值&#xff0c;步骤很繁琐&#xff0c;在.Net 3.0时代&#xff0c;微软引入匿名类的概念&#xff0c;简化了代码编写&#xff0c;提高了开发效率。 匿名类的声明语法&#xff1a; var objnew {字段…

第九节:委托和事件(1)(委托的发展历史、插件式编程、多播委托)

一. 委托的发展历史和基本用法 说起委托&#xff0c;每个人可能都会对他有不同的理解&#xff0c;结合实战中委托的使用&#xff0c;我对其理解是&#xff1a;委托和类一样&#xff0c;是用户的一个自定义类型&#xff0c;委托可以有参数、有返回值&#xff0c;委托的关键字是d…

第十节:委托和事件(2)(泛型委托、Func和Action、事件及与委托的比较)

一. 泛型委托 所谓的泛型委托&#xff0c;即自定义委托的参数可以用泛型约束&#xff0c;同时内置委托Func和Action本身就是泛型委托。 将上一个章节中的Calculator类中的方法用自定义泛型委托重新实现一下。 1 public class Calculator22 {3 //传统解决方案一&am…

java+sm4+加密算法_SM4加密算法实现Java和C#相互加密解密

https://www.cnblogs.com/miaoziblog/p/9040473.html近期由于项目需要使用SM4对数据进行加密&#xff0c;然后传给Java后台&#xff0c;Java后台使用的也是SM4的加密算法但是就是解密不正确&#xff0c;经过一步步调试发现Java中好多数据类型与C#的相同的数据类型是存在不同的比…

DotNet进阶系列

一. 回顾历史 回顾个人发展历程&#xff0c;自2012年初次接触开发至今(2018年)已经有六个年头&#xff0c;这期间陆陆续续学习并掌握了不少技术&#xff0c;C#语言、ORM框架、多线程技术、设计模式、前端技术、MVC、MVVM框架思想等等&#xff0c;每种技术随着多次使用&#xff…

第十一节:特性(常见的特性标签、自定义特性、特性的使用案例)

一. 基本概念 1. 什么是特性? MSDN官方给出的定义时&#xff1a;公共语言运行时允许添加类似关键字的描述声明&#xff0c;叫做特性&#xff0c;它对程序中的元素进行标注&#xff0c;如类型、字段、方法和属性等。Attribute和Microsoft .Net Framework文件的元数据&#xff…

第十二节:Lambda、linq、SQL的相爱相杀(1)

一. 谈情怀 Lambda、Linq、SQL伴随着我的开发一年又一年&#xff0c;但它们三者并没有此消彼长&#xff0c;各自占有这一定的比重&#xff0c;起着不可替代的作用。 相信我们最先接触的应该就是SQL了&#xff0c;凡是科班出身的人&#xff0c;大学期间都会学习SQL Server数据库…

php java 共享session_PHP 实现多服务器共享 SESSION 数据

一、问题起源稍大一些的网站&#xff0c;通常都会有好几个服务器&#xff0c;每个服务器运行着不同功能的模块&#xff0c;使用不同的二级域名&#xff0c;而一个整体性强的网站&#xff0c;用户系统是统一的&#xff0c;即一套用户名、密码在整个网站的各个模块中都是可以登录…

第十三节:Lambda、linq、SQL的相爱相杀(2)

一. Linq开篇 1.Where用法 linq中where的用法与SQL中where的用法基本一致。 1 #region 01-where用法2 {3 //1. where用法4 //1.1 查询账号为admin的用户信息5 Console.WriteLine("------------…

第十四节:Lambda、linq、SQL的相爱相杀(3)

一. SQL 开篇 1. where用法 1    #region 封装EF调用SQL语句查询 2 public static List<T> ExecuteQuery<T>(string sql, params SqlParameter[] pars) 3 { 4 return db.Database.SqlQuery<T>(sql, pars).ToList(); 5 …

第十五节:Expression表达式目录树(与委托的区别、自行拼接、总结几类实例间的拷贝)

一. 基本介绍 回忆&#xff1a; 最早接触到表达式目录树(Expression)可能要追溯到几年前使用EF早期的时候&#xff0c;发现where方法里的参数是Expression<Func<T,bool>>这么一个类型&#xff0c;当初不是很理解&#xff0c;只是知道传入lambda表达式使用即可&…

IIS Web 服务器/ASP.NET 运行原理基本知识概念整理

前言&#xff1a; 记录 IIS 相关的笔记还是从公司笔试考核题开始的&#xff0c;问 Application Pool 与 AppDomain 的区别&#xff1f; 促使我对进程池进了知识的学习&#xff0c;所以记录一下学习的笔记。 我们知道现在 .NET 就业来看&#xff0c;80% 的 .NET 程序员都是从事 …

Http请求处理流程

从一个页面比如www.xuxiaoyu.net的请求开始如何就能打开blogs页面的呢&#xff1f;这其中发生了什么样的东西&#xff1f; Http请求(Http Request) 当服务器&#xff08;IIS&#xff09;接受到一个Http请求的时候进行以下步骤的处理&#xff1a; 1)服务器获取所请求的页面的后缀…

iis到w3wp的数据流及工作原理

HTTP.sys->IO线程-CLR线程池中的worker线程处理 IO线程只负责把请求交给Worker线程或者放入进程池级别的队列,然后又去HTTP.SYS的队列中处理其它的请求

php云解析播放器,xyplay云解析PHPV3.4.1优化稳定版视频解析

演示地址&#xff1a;如有演示站请以演示为准&#xff0c;无演示站以截图为准,源码太多服务器有限&#xff0c;无法搭建所有源码演示站&#xff0c;请谅解&#xff01;新手购买指导&#xff1a;1.在本站注册账号 丨 2.登录已注册账号充值源码所需金币 丨 3.登录账号下载所需源码…

php version.,PHP_VERSION指什么

PHP_VERSION (string)当前的PHP版本&#xff0c;以字符串形式“ major.minor.release [extra]”表示。 (推荐学习&#xff1a;PHP视频教程)例如&#xff1a;<?php // PHP_VERSION_ID 自 PHP 5.2.7 起有效&#xff0c;// 如果我们的版本低于该版本&#xff0c;则用以下代码来…

C# async 和 await 理解

先假设如下场景&#xff1a; 主函数 Main&#xff0c;循环等待用户输入&#xff1b; 计算函数 Cal&#xff0c;耗时计算大量数据&#xff1b; class Test {static int Main(string[] args){while(true){// 等待用户输入}}public static int Cal() {int sum 0;for (int i …

C# 彻底搞懂async/await

前言 Talk is cheap, Show you the code first&#xff01; private void button1_Click(object sender, EventArgs e) {Console.WriteLine("111 balabala. My Thread ID is :" Thread.CurrentThread.ManagedThreadId);AsyncMethod();Console.WriteLine("222 …