第五节:泛型(泛型类、接口、方法、委托、泛型约束、泛型缓存、逆变和协变)

一. 泛型诞生的背景

  在介绍背景之前,先来看一个案例,要求:分别输出实体model1、model2、model3的id和name值,这三个实体有相同的属性名字id和name。

复制代码

 1  public class myUtils2     {3         //要求:分别输出实体model1、model2、model3的id和name值,这三个实体有相同的属性名字id和name4 5         //传统的解决方案(一):由于三个不同的实体,所以要声明三个不同的方法来输出6         /*7         缺点:该解决方案十分繁琐,明明相同的属性,不得不声明三个不同的方法,造成代码的大量冗余8         */9 
10         public static void showM1(model1 m1)
11         {
12             Console.WriteLine("id值为:" + m1.id + "  name值为:" + m1.name);
13         }
14 
15         public static void showM2(model2 m2)
16         {
17             Console.WriteLine("id值为:" + m2.id + "  name值为:" + m2.name);
18         }
19 
20         public static void showM3(model3 m3)
21         {
22             Console.WriteLine("id值为:" + m3.id + "  name值为:" + m3.name);
23         }
24 
25 
26         //传统的解决方案(二):使用Object类型来解决该问题
27         //原理:object是所有类型的父类,所有用到父类的地方都可以用子类去代替,即:里氏替换原则
28         /*
29              缺点:需要记住可能会传进来哪几种类型;最大的问题是值类型和引用类型之间的互换(即拆箱和装箱)严重影响性能
30          */
31 
32         public static void showObj(object obj)
33         {
34             if (obj.GetType() == typeof(model1))
35             {
36                 model1 m = (model1)obj;
37                 Console.WriteLine("id值为:" + m.id + "  name值为:" + m.name);
38             }
39             else if (obj.GetType() == typeof(model2))
40             {
41                 model2 m = (model2)obj;
42                 Console.WriteLine("id值为:" + m.id + "  name值为:" + m.name);
43             }
44             else if (obj.GetType() == typeof(model3))
45             {
46                 model3 m = (model3)obj;
47                 Console.WriteLine("id值为:" + m.id + "  name值为:" + m.name);
48             }
49 
50         }
51 
52         //基于以上两种传统的解决方案都缺点明显,所以在 .Net 2.0的时候,推出了一个通用语言运行时(CRL)的新特性即:泛型。
53         /*
54             泛型为.NET框架引入了类型参数(type parameters)的概念。类型参数使得设计类和方法时,不必确定一个或多个具体参数,其的具体参数可延迟到客户代码中声明、实现。
55             这意味着使用泛型的类型参数T,可以多种形式调用,运行时类型转换避免了装箱操作的代价和风险。
56 
57          */
58        
59     }

复制代码

  基于以上两种传统的解决方案都缺点明显,所以在 .Net 2.0的时候,推出了一个通用语言运行时(CLR)的新特性即:泛型。泛型为.NET框架引入了类型参数(type parameters)的概念,它属于System.Collections.Generic命名空间下。类型参数使得设计类和方法时,不必确定一个或多个具体参数,其的具体参数可延迟到客户代码中声明、实现。

  这意味着使用泛型的类型参数T,可以多种形式调用,运行时类型转换避免了装箱操作的代价和风险。

二. 泛型的引入

   为了解决上述问题,我们这里引入泛型的概念来解决代码冗余的问题和性能低下的问题。

  这里统一说明一下:model1、model2、model3实体均继承与ModelFather实体,ModelFather实体中有两个属性,id和name,下同。 

复制代码

 1        /// <summary>2         /// 泛型方法的引入3         /// </summary>4         /// <typeparam name="T">T为泛型的一个标记,也可以用别的字母代替</typeparam>5         /// <param name="t"></param>6         public static void showModel<T>(T t)7         {8             Console.WriteLine(t);9         }
10 
11         /// <summary>
12         /// 泛型约束的引入,如果要输出实体中的值,需要配合“基类约束”方可以实现
13         /// </summary>
14         /// <typeparam name="T"></typeparam>
15         /// <param name="t"></param>
16         public static void showModelDetils<T>(T t) where T : ModelFather
17         {
18             Console.WriteLine("id值为:" + t.id + "  name值为:" + t.name);
19         }
20 
21 
22         //总结:
23         /*
24             1. 以上两个方法均为泛型方法,T代表的类型在使用时才声明,俗称“延迟声明”。
25             2. 如果要使用类中的属性时,需要配合泛型的“基类约束”来实现
26         */

复制代码

  总结:

    1. 以上两个方法均为泛型方法,T代表的类型在使用时才声明,俗称“延迟声明”。

    2. 如果要使用类中的属性时,需要配合泛型的“基类约束”来实现。

        说明:除了泛型方法外,还有泛型接口、泛型委托等,同样泛型约束除了“基类约束”外,还有其他约束。

三. 泛型的种类

  泛型包括:泛型方法、泛型类、泛型接口、泛型委托四类。

  这里主要介绍泛型方法,在后续会配合泛型的五种约束继续深入介绍。

 View Code

 View Code

 View Code

 View Code

四.泛型约束

(一). 泛型约束主要分为以下五种:

  1. 基类约束:where T:<基类名>

  2. 接口约束:where T:<接口名称> 约束的接口也可以是泛型的

  3. 无参构造函数约束:where T: new() 提供的任何类型参数都必须具有可访问的无参数(或默认)构造函数。当与其他约束一起使用时,new() 约束必须最后指定。

  4. 值类型约束:where T:struct 类型参数必须是值类型,可以指定除 Nullable 以外的任何值类型。

  5. 引用类型约束: where T:class 类型参数必须是引用类型,也适用于任何类、接口、委托或数组类型。当与其他约束一起使用时,class 约束必须最先指定。

(二). 多参数约束:

  可以写多个where条件

  public static void ShowModel<T, A>(T model1, A model2)

    where T : ModelFather

    where A : model3

(三):多条件约束:

  当有多个条件约束时,无参构造函数约束要写到最后

  public void ShowManyCon<T>(T t) where T : class, IWork, ISport, new()

(四):分别测试各种约束

  A:各种约束的代码

复制代码

 1  public class genericsConstraint2     {3  4         /// <summary>5         /// 1. 基类约束和接口约束6         /// </summary>7         /// <typeparam name="T"></typeparam>8         /// <param name="t"></param>9         public void Show<T>(T t) where T : People, IWork
10         {
11             Console.WriteLine("id值为:" + t.id + "  name值为:" + t.name);
12             t.Say();
13             t.Work();
14         }
15         /// <summary>
16         /// 2. 无参构造函数约束
17         /// </summary>
18         /// <typeparam name="T"></typeparam>
19         /// <param name="t"></param>
20         public void ShowNo<T>(T t) where T : new()
21         {
22             T t1 = new T();
23             Console.WriteLine(t1);
24 
25         }
26         /// <summary>
27         /// 3. 值类型约束
28         /// C#值类型包括:结构体、数据类型(整型、字符型、浮点型、decimal型)、bool型、枚举、可空类型
29         /// </summary>
30         /// <typeparam name="T"></typeparam>
31         /// <param name="t"></param>
32         public void ShowZhi<T>(T t) where T : struct
33         {
34             Console.WriteLine(t);
35         }
36         /// <summary>
37         /// 4. 引用类型约束
38         /// C#引用类型包括:数组、类、接口、委托、object、字符串
39         /// </summary>
40         /// <typeparam name="T"></typeparam>
41         /// <param name="t"></param>
42         public void ShowYin<T>(T t) where T : class
43         {
44             Console.WriteLine(t);
45         }
46         /// <summary>
47         /// 5. 多参数约束
48         /// </summary>
49         /// <typeparam name="T"></typeparam>
50         /// <typeparam name="G"></typeparam>
51         /// <param name="t"></param>
52         /// <param name="g"></param>
53         public void ShowMany<T, G>(T t, G g)
54             where T : People
55             where G : IWork
56         {
57             Console.WriteLine(t);
58             Console.WriteLine(g);
59         }
60         /// <summary>
61         /// 6. 多条件约束
62         /// </summary>
63         /// <typeparam name="T"></typeparam>
64         /// <param name="t"></param>
65         public void ShowManyCon<T>(T t) where T : class, IWork, ISport, new()
66         {
67 
68         }

复制代码

  B:各种实体代码

复制代码

 1 namespace Generics._04_泛型约束2 {3     /// <summary>4     /// People类5     /// </summary>6     public class People7     {8         public string id { get; set; }9 
10         public string name { get; set; }
11 
12         public void Say()
13         {
14             Console.WriteLine("我会说话");
15         }
16 
17     }
18     /// <summary>
19     /// Chinese类
20     /// </summary>
21     public class Chinese : People, ISport, IWork
22     {
23         public void Sport()
24         {
25             Console.WriteLine("我在运动");
26         }
27 
28         public void Work()
29         {
30             Console.WriteLine("我在工作");
31         }
32     }
33     /// <summary>
34     /// Janpanese类
35     /// </summary>
36     public class Janpanese : IWork
37     {
38         public string id { get; set; }
39 
40         public string name { get; set; }
41         public void Work()
42         {
43             Console.WriteLine("我在工作");
44         }
45     }
46     /// <summary>
47     /// YanTai
48     /// </summary>
49     public class YanTai : Chinese
50     {
51 
52     }
53     /// <summary>
54     /// IWork接口
55     /// </summary>
56     public interface IWork
57     {
58         void Work();
59     }
60     /// <summary>
61     /// ISport接口
62     /// </summary>
63     public interface ISport
64     {
65         void Sport();
66     }
67     /// <summary>
68     /// 构造函数无参的 类
69     /// </summary>
70     public class Test1
71     {
72         public Test1()
73         {
74 
75         }
76     }
77     /// <summary>
78     /// 构造函数有参的类
79     /// </summary>
80     public class Test2
81     {
82         public Test2(string id,string name)
83         {
84            
85         }
86     }
87 
88 
89 }

复制代码

  C:初始化代码

复制代码

 1         //1.四个实体类2             People people = new People()3             {4                 id = "p1",5                 name = "mr1"6             };7             Chinese chinese = new Chinese()8             {9                 id = "p2",
10                 name = "mr2"
11             };
12             Janpanese janpanese = new Janpanese()
13             {
14             };
15             YanTai yanTai = new YanTai()
16             {
17                 id = "p3",
18                 name = "mr3"
19             };
20             //2. 构造函数有参数和无参数的两个类
21             Test1 test1 = new Test1();
22             Test2 test2 = new Test2("pp","maru");
23             //3. 声明一个值类型和一个引用类型
24             int num = 12; //值类型
25             YanTai yt2 = new YanTai();   //引用类型

复制代码

  D:代码调用

复制代码

 1          Console.WriteLine("------------------------------------四  泛型约束------------------------------------");2             //4.1 基类约束和接口约束3             Console.WriteLine("------------------------------------4.1 基类约束和接口约束------------------------------------");4             genericsConstraint gc = new genericsConstraint();5             //gc.Show<People>(people);     //People类没有实现IWork接口6             gc.Show<Chinese>(chinese);7             //gc.Show<Janpanese>(janpanese); //Janpanese只实现了IWork接口,但不满足基类约束(即使他有和基类相同的属性也不行)8             gc.Show<YanTai>(yanTai);9             //4.2 无参构造函数约束
10             Console.WriteLine("------------------------------------4.2 无参构造函数约束------------------------------------");
11             gc.ShowNo<Test1>(test1);
12             // gc.ShowNo<Test2>(test2);    //Test2的构造函数有参数,所以不满足无参构造函数约束
13             //4.3 值类型约束
14             Console.WriteLine("------------------------------------4.3 值类型约束------------------------------------");
15             gc.ShowZhi<int>(num);
16             //gc.ShowZhi<YanTai>(yt2);     //YanTai类 是引用类型,不满足值类型约束
17             //4.4 引用类型约束
18             Console.WriteLine("------------------------------------4.4 引用类型约束------------------------------------");
19             //gc.ShowYin<int>(num);          //int类型 是值类型,不满足引用类型约束
20             gc.ShowYin<YanTai>(yt2);
21             //4.5 多参数约束
22             Console.WriteLine("------------------------------------4.5 多参数约束------------------------------------");
23             gc.ShowMany<People, Chinese>(people, chinese);
24             //4.6 多条件约束
25             Console.WriteLine("------------------------------------4.6 多条件约束------------------------------------");
26             Console.WriteLine("针对多条件约束,这里不做测试");

复制代码

  D:测试结果

五. 泛型的原理和好处

(一). 泛型的原理:

  延时声明,在运行时进行编译

(二). 泛型的好处:

  1.减少代码冗余量,精简代码

  2.避免了拆箱和装箱过程过程中代理的性能损失

  3.结合IDE的只能提示,提高了开发效率

下面测试一下:普通方法、使用Object类型、使用泛型 三种情况对同一个数据进行处理,耗时情况

复制代码

 1  public class utils2     {3         /// <summary>4         /// 正常方法5         /// </summary>6         /// <param name="iParameter"></param>7         public static void ShowCommon(int iParameter)8         { }9         /// <summary>
10         /// object方法
11         /// </summary>
12         /// <param name="oParameter"></param>
13         public static void ShowObject(object oParameter)
14         { }
15         /// <summary>
16         /// 原型方法
17         /// </summary>
18         /// <typeparam name="T"></typeparam>
19         /// <param name="tParameter"></param>
20         public static void ShowGeneric<T>(T tParameter)
21         { }
22     }

复制代码

复制代码

 1         Console.WriteLine("----------测试正常方法、Object方法、泛型方法各自耗时情况------------");2             long commonTime = 0;3             long objectTime = 0;4             long genericTime = 0;5             {6                 Stopwatch stopwatch = new Stopwatch();7                 stopwatch.Start();8 9                 for (int i = 0; i < 1000000000; i++)
10                 {
11                     utils.ShowCommon(ivalue);
12                 }
13                 stopwatch.Stop();
14                 commonTime = stopwatch.ElapsedMilliseconds;
15             }
16             {
17                 Stopwatch stopwatch = new Stopwatch();
18                 stopwatch.Start();
19 
20                 for (int i = 0; i < 1000000000; i++)
21                 {
22                     utils.ShowObject(ivalue);
23                 }
24                 stopwatch.Stop();
25                 objectTime = stopwatch.ElapsedMilliseconds;
26             }
27             {
28                 Stopwatch stopwatch = new Stopwatch();
29                 stopwatch.Start();
30 
31                 for (int i = 0; i < 1000000000; i++)
32                 {
33                     utils.ShowGeneric<int>(ivalue);
34                 }
35                 stopwatch.Stop();
36                 genericTime = stopwatch.ElapsedMilliseconds;
37             }
38             Console.WriteLine("commonTime = {0} objectTime = {1} genericTime = {2}", commonTime, objectTime, genericTime);

复制代码

  测试结果:

      结论:正常的方法和泛型方法耗时基本一致,泛型方法甚至用的时间更短,但是采用object类型转换的方法,耗时明显长于其他两种

 

六. 补充default(T)

了解:

  1.  在泛型中如果需要返回泛型类型的默认值则会用到这个关键字。

  2. T是值类型而非结构的则default(T) 数值类型返回0,字符串返回空。

  3.  是非引用类型是结构时候返回初始化为零或空的每个结构成员。

  4.  引用类型返回NULL

  5. 其实就是为了返回默认值,比如int i =0;这样是可以的,但是int i=null是不可以的,但是泛型的时候不知道是值类型还是引用类型所以不知道如何赋默认值。

用这个关键字就解决了这个问题

 

七. 泛型缓存

1. 知识普及:如果一个(普通)类中有静态变量或者静态构造函数,当实例化的时候,CLR会优先初始化静态变量和静态构造函数,且只有在第一次实例化的时候进行初始化,后续都不在进行初始化。(PS:利用这两个特性可以创建单例模式)

   特别注意:如果是泛型类的话,不同类型的第一次实例化的时候都要初始化静态变量和静态构造函数(每个不同的T,都会生成一份不同的副本)。

2. 先用一普通例子来抛砖引玉:

  新建一个CommonClass类,里面有静态字段和静态方法,然后调用4次,发现每次输出的时间都是相同,证明静态字段和静态构造函数只有第一次实例化的时候才调用。

  或者通过加断点的形式,也可以发现,只有在第一次实例化的时候才能进入静态字段和静态构造函数,同样证明了上述结论。

3. 下面建一个泛型类GenericsClass<T>,里面有静态字段和静态方法,然后分别传入不同的类型,int、string、int、string,发现输出的时间第2次比第1次时间晚约2s,但是第1次和第3次,第2次和第4次的时间是相同,这就是泛型缓存

4. 最后自己总结一下泛型缓存的定义:

  对于泛型类而言,不同类型都会生成不同的副本(即都要调用静态的构造函数和静态字段),但相同的类型,实例化一次后,再次实例化,将不会在生成副本(即不再调用静态类和静态构造函数),这就是泛型缓存。

代码分享:

复制代码

 1      /// <summary>2     /// 一个普通类3     /// </summary>4     public class CommonClass5     {6         static CommonClass()7         {8             _InitTime = string.Format("调用构造函数的时间:{0}", DateTime.Now.ToString("yyyyMMddHHmmss.fff"));9         }
10         private static string _InitTime = "";
11         public void show()
12         {
13             Console.WriteLine(_InitTime);
14         }
15     }
16     /// <summary>
17     /// 泛型类
18     /// </summary>
19     /// <typeparam name="T"></typeparam>
20     public class GenericsClass<T>
21     {
22         static GenericsClass()
23         {
24             _InitTime = string.Format("调用构造函数的时间:{0}", DateTime.Now.ToString("yyyyMMddHHmmss.fff"));
25         }
26         private static string _InitTime = "";
27         public void show()
28         {
29             Console.WriteLine(_InitTime);
30         }
31     }

复制代码

复制代码

 1      public static void ShowGenericsCacheDemo()2         {3 4             {5                 Console.WriteLine("1. 测试普通类");6                 CommonClass c1 = new CommonClass();7                 c1.show();8                 Thread.Sleep(2000);9                 CommonClass c2 = new CommonClass();
10                 c2.show();
11                 Thread.Sleep(2000);
12                 CommonClass c3 = new CommonClass();
13                 c3.show();
14             }
15             {
16                 Console.WriteLine("2. 测试泛型类");
17                 GenericsClass<int> c1 = new GenericsClass<int>();
18                 c1.show();
19                 Thread.Sleep(2000);
20                 GenericsClass<string> c2 = new GenericsClass<string>();
21                 c2.show();
22                 Thread.Sleep(2000);
23                 GenericsClass<int> c3 = new GenericsClass<int>();
24                 c3.show();
25                 Thread.Sleep(2000);
26                 GenericsClass<string> c4 = new GenericsClass<string>();
27                 c4.show();
28             }

复制代码

结果:

 

 

八. 逆变和协变

1. 目标:了解是什么即可,实际中用的很少。

2. 事前准备:BaseClass和DerivedClass两个类,DerivedClass类继承BaseClass类。

复制代码

 1  public class BaseClass2     {3         public string id { get; set; }4 5         public int age { get; set; }6 7         public string name { get; set; }8     }9    public class DerivedClass : BaseClass
10     {
11 
12     }

复制代码

3. 逆变:借助Action<in T>,将父类参数的委托赋值给子类参数的委托

4. 协变:借助IEnumerable<out T>,可以将原本有继承关系的两个类的集合关联起来

分享相关代码:

复制代码

 1           {2                 //里氏替换原则(也是多态的一种)3                 BaseClass bClass = new DerivedClass();4             }5             {6                 //推断:List集合进行继承(编译不过,报错)7                 //List<BaseClass> bClassList = new List<DerivedClass>();8             }       9             {
10                 //借助Action<in T>,将父类参数的委托赋值给子类参数的委托
11                 //这就是 → “逆变”
12                 Action<BaseClass> bAction = (a) => { Console.WriteLine(a.GetType().Name); };
13                 Action<DerivedClass> dAction = bAction;
14                 dAction(new DerivedClass());
15             }
16             {
17                 //借助IEnumerable<out T>,可以将原本有继承关系的两个类的集合关联起来
18                 //这就是 → “协变”
19                 IEnumerable<BaseClass> bClassList = new List<DerivedClass>();
20             }

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

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

相关文章

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

一. 加载dll,读取相关信息 1. 加载程序集的三种方式 调用Assembly类下的三个方法&#xff1a;Load、LoadFile、LoadFrom。 1       //1.1 Load方法&#xff1a;动态默认加载当前路径下的(bin)下的dll文件,不需要后缀 2 Assembly assembly Assembly.Load(&…

第七节:语法总结(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 …