目录

泛型

泛型类

泛型方法

委托

委托基本知识

泛型委托

Action委托

Func委托

多播委托

匿名函数

lambda表达式

观察者设计模式(事件)

LINQ查询语句

反射和特性

特性

线程

委托创建线程

Thread创建线程

线程池

任务

连续任务

任务层次结构


泛型

泛型类

      class ClassA<T,A> {//T代表一个数据类型,当使用classA进行构造的时候,需要制定T的类型private T a;private T b;private A c;public ClassA(T a, T b ){this.a = a;this.b = b;}public string  GetSum(){return a +""+ b;}}var o1 = new ClassA<int>(12,34);//当我们利用泛型类构造的时候,需要制定泛型的类型string s = o1.GetSum();Console.WriteLine(s);

泛型方法

 public static string GetSum<T,T2,T3,T4>(T a, T b){return a + "" + b;}Console.WriteLine(GetSum<int,int,int,int>(12,34)); 

委托

委托基本知识

 private delegate string GetAString();//定义了一个委托类型,这个委托类型的名字叫做GetAStringstatic void Main(string[] args){int x = 40;string s = x.ToString();//tostring 方法用来把数据转换成字符串Console.WriteLine(s);//使用委托类型 创建实例GetAString a = new GetAString(x.ToString);//a指向了x中的tostring方法GetAString a = x.ToString;string s = a();//通过委托实例去调用 x中的tostring方法string s = a.Invoke();//通过invoke方法调用a所引用的方法Console.WriteLine(s);//通过委托类型是调用一个方法,跟直接调用这个方法 作用是一样的//实例2 使用委托类型作为方法的参数PrintString method = Method1;PrintStr(method);method = Method2;PrintStr(method);Console.ReadKey();}private delegate void PrintString();static void PrintStr( PrintString print ){print();}static void Method1() {Console.WriteLine("method1");}

泛型委托

    //泛型委托public delegate int Delcompare<T>(T n1,T n2);person[] people = { new person() {Age=12 },new person() { Age=22} };string max = GetMax(names, Compare2);person p = GetMax(people, Compare3);//返回任意数组中的最大值public static T GetMax<T>(T[] nums, Delcompare<T> del)//传入一个委托函数,就是比较方法{T max = nums[0];for (int i = 0; i < nums.Length; i++){if (del(max, nums[i]) < 0){max = nums[i];}}return max;}public static int Compare1(int n1, int n2){return n1 - n2;}public static int Compare2(string n1, string n2){return n1.Length - n2.Length;}public static int Compare3(person n1, person n2){return n1.Age - n2.Age;}public class person{public int Age{get;set;}}

Action委托

        static void PrintString(){Console.WriteLine("hello world.");}static void PrintInt(int i){Console.WriteLine(i);}static void PrintString(string str){Console.WriteLine(str);}static void PrintDoubleInt(int i1, int i2){Console.WriteLine(i1+i2);}Action a = PrintString;//action是系统内置(预定义)的一个委托类型,它可以指向一个没有返回值,没有参数的方法Action<int> a=PrintInt;//定义了一个委托类型,这个类型可以指向一个没有返回值,有一个int参数的方法Action<string> a = PrintString;//定义了一个委托类型,这个类型可以指向一个没有返回值,有一个string参数的方法 在这里系统会自动寻找匹配的方法Action<int, int> a = PrintDoubleInt;a(34, 23);Console.ReadKey();//action可以后面通过泛型去指定action指向的方法的多个参数的类型 ,参数的类型跟action后面声明的委托类型是对应着的

Func委托

        static int Test1(){return 1;}static int Test2(string str){Console.WriteLine(str);return 100;}static int Test3(int i, int j){return i + j;}Func<int> a = Test1;//func中的泛型类型制定的是 方法的返回值类型Console.WriteLine(a());Func<string, int> a = Test2;//func后面可以跟很多类型,最后一个类型是返回值类型,前面的类型是参数类型,参数类型必须跟指向的方法的参数类型按照顺序对应Func<int, int, int> a = Test3;//func后面必须指定一个返回值类型,参数类型可以有0-16个,先写参数类型,最后一个是返回值类型int res = a(1, 5);Console.WriteLine(res);Console.ReadKey();

多播委托

前面使用的委托都只包含一个方法的调用,但是委托也可以包含多个方法,这种委托叫做多播委托。

使用多播委托就可以按照顺序调用多个方法,多播委托只能得到调用的最后一个方法的结果,一般我们把多播委托的返回类型声明为void。

多播委托包含一个逐个调用的委托集合,如果通过委托调用的其中一个方法抛出异常,整个迭代就会停止。

        static void Test1(){Console.WriteLine("test1");//throw new Exception();}static void Test2(){Console.WriteLine("test2");}//多播委托Action a = Test1;//a = Test2;a += Test2;//表示添加一个委托的引用 //a -= Test1;//a -= Test2;//if(a!=null)//    a();//当一个委托没有指向任何方法的时候,调用的话会出现异常nullDelegate[] delegates = a.GetInvocationList(); //遍历委托foreach (Delegate de in delegates){de.DynamicInvoke();}

匿名函数

有另外一种使用委托的方式,不用去定义一个方法,应该说是使用匿名方法(方法没有名字)。

Func<int,int,int> plus = delegate (int a,int b){int temp = a+b;return temp;
};//格式位delegate(参数){方法体}
int res = plus(34,34);
Console.WriteLine(res);

lambda表达式

 Func<int, int, int> plus = (arg1, arg2) =>// lambda表达式的参数是不需要声明类型的{return arg1 + arg2;};Func<int, int> test2 = a => a+1;//lambda表示的参数只有一个的时候,可以不加上括号  当函数体的语句只有一句的时候,我们可以不加上大括号 也可以不加上return语句

观察者设计模式(事件)

事件(Event)是类或对象向其他类或对象通知发生的事情的一种特殊签名的委托.

public event 委托类型 事件名;

有三只动物,猫(名叫Tom),还有两只老鼠(Jerry和Jack),当猫叫的时候,触发事件(CatShout),然后两只老鼠开始逃跑(MouseRun)。

接下来用代码来实现。(设计模式-观察者模式)

 class Cat{public string name;public string colour;public event Action Run; //声明事件委托public Cat(string name, string colour){this.name = name;this.colour = colour;}public void Coming(){Console.WriteLine(this.colour+"的猫"+this.name+"  来了");this.Run(); //调用事件委托}}class Mouse{public string name;public string colour;public Cat cat;public Mouse(string name, string colour,Cat cat){this.name = name;this.colour = colour;this.cat = cat;cat.Run += run; //注册事件}public void run(){Console.WriteLine(colour+"的猫"+name+":说猫来了,快跑");}}Cat cat1 = new Cat("Tom", "蓝色");Mouse mouse1 = new Mouse("mouse1", "red", cat1);Mouse mouse2 = new Mouse("mouse2", "blue", cat1);Mouse mouse3 = new Mouse("mouse3", "yellow", cat1);cat1.Coming();//触发事件

LINQ查询语句

            //初始化武林高手var masterList = new List<MartialArtsMaster>(){new MartialArtsMaster() {Id = 1, Name = "黄蓉", Age = 18, Menpai = "丐帮", Kongfu = "打狗棒法", Level = 9},new MartialArtsMaster() {Id = 2, Name = "洪七公", Age = 70, Menpai = "丐帮", Kongfu = "打狗棒法", Level = 10},new MartialArtsMaster() {Id = 3, Name = "郭靖", Age = 22, Menpai = "丐帮", Kongfu = "降龙十八掌", Level = 10},new MartialArtsMaster() {Id = 4, Name = "任我行", Age = 50, Menpai = "明教", Kongfu = "葵花宝典", Level = 1},new MartialArtsMaster() {Id = 5, Name = "东方不败", Age = 35, Menpai = "明教", Kongfu = "葵花宝典", Level = 10},new MartialArtsMaster() {Id = 6, Name = "林平之", Age = 23, Menpai = "华山", Kongfu = "葵花宝典", Level = 7},new MartialArtsMaster() {Id = 7, Name = "岳不群", Age = 50, Menpai = "华山", Kongfu = "葵花宝典", Level = 8},new MartialArtsMaster() {Id = 8, Name = "令狐冲", Age = 23, Menpai = "华山", Kongfu = "独孤九剑", Level = 10},new MartialArtsMaster() {Id = 9, Name = "梅超风", Age = 23, Menpai = "桃花岛", Kongfu = "九阴真经", Level = 8},new MartialArtsMaster() {Id = 10, Name = "黄药师", Age = 23, Menpai = "梅花岛", Kongfu = "弹指神通", Level = 10},new MartialArtsMaster() {Id = 11, Name = "风清扬", Age = 23, Menpai = "华山", Kongfu = "独孤九剑", Level = 10}};//初始化武学var kongfuList = new List<Kongfu>(){new Kongfu() {Id = 1, Name = "打狗棒法", Power = 90},new Kongfu() {Id = 2, Name = "降龙十八掌", Power = 95},new Kongfu() {Id = 3, Name = "葵花宝典", Power = 100},new Kongfu() {Id = 4, Name = "独孤九剑", Power = 100},new Kongfu() {Id = 5, Name = "九阴真经", Power = 100},new Kongfu() {Id = 6, Name = "弹指神通", Power = 100}};//查询所有武学级别大于8的武林高手//var res = new List<MartialArtsMaster>();//foreach (var temp in masterList)//{//    if (temp.Level > 8)//    {//        res.Add(temp);//    }   //}//1,使用LINQ做查询( 表达式写法)//查询所有武学级别大于8的武林高手var res = from m in masterList //自动遍历集合中的每个对象mwhere m.Level > 8 && m.Menpai=="丐帮"select m;//2,扩展方法的写法var res1 = masterList.Where(Test);var res2 = masterList.Where(m=>m.Level>8); //lambda表达式写法//3,LINQ 联合查询//取得所学功夫的杀伤力大于90 的武林高手var res3 = from m in masterListfrom k in kongfuListwhere m.Kongfu == k.Name && k.Power > 90select new { master = m, kongfu = k };//选择多个字段//select m;//扩展方法用法var res4 = masterList.SelectMany(k => kongfuList, (m, k) => new { master = m, kongfu = k }).Where(x => x.master.Kongfu == x.kongfu.Name && x.kongfu.Power > 90);//4,对查询结果做排序 orderby (descending)var res5 = from m in masterListwhere m.Level > 8// orderby m.Age descending//加descending就是倒序orderby m.Level,m.Age //按照多个字段进行排序,如果字段的属性相同,就按照第二个属性排序select m;//5,join on 集合联合var res6 = from m in masterListjoin k in kongfuList on m.Kongfu equals k.Namewhere k.Power > 90select m;//6,分组查询 into groups (把武林高手按照所学功夫分类,看一下那个功夫修炼的人数最多)var res7 = from k in kongfuListjoin m in masterList on k.Name equals m.Kongfuinto groupsselect new { kongfu = k, count = groups.Count() };//7,按照自身字段分组 groupvar res8 = from m in masterListgroup m by m.Kongfuinto gselect new { count = g.Count(), key = g.Key };//g.Key Key表示是按照那个属性分的组//8,量词操作符 any all 判断集合中是否满足某个条件或者全部满足bool res9 = masterList.Any(m => m.Menpai == "长留");Console.WriteLine(res);bool res10 = masterList.All(m => m.Menpai == "丐帮");Console.WriteLine(res);//显示信息foreach (var item in res8){Console.WriteLine(item.ToString());}}static bool Test(MartialArtsMaster master){if (master.Level > 8) return true;return false;}

反射和特性

1.程序是用来处理数据的,文本和特性都是数据,而我们程序本身(类的定义和BLC中的类)这些也是数据。
2.有关程序及其类型的数据被称为元数据(metadata),它们保存在程序的程序集中。
3.程序在运行时,可以查看其它程序集或其本身的元数据。一个运行的程序查看本身的元数据或者其他程序集的元数据的行为叫做反射。

Type位于System.Reflection命名空间下

Assembly类在System.Reflection命名空间中定义,它允许访问给定程序集的元数据,它也包含了可以加载和执行程序集。

          //每一个类对应一个type对象,这个type对象存储了这个类 有哪些方法跟哪些数据 哪些成员MyClass my = new MyClass();//一个类中的数据 是存储在对象中的, 但是type对象只存储类的成员Type type = my.GetType();//通过对象获取这个对象所属类 的Type对象Console.WriteLine(type.Name);//获取类的名字Console.WriteLine(type.Namespace);//获取所在的命名空间Console.WriteLine(type.Assembly);//返回程序集FieldInfo[] array= type.GetFields();//只能获取public 字段foreach (FieldInfo info in array){Console.Write(info.Name+" ");}PropertyInfo[] array2 = type.GetProperties();//获取属性foreach (PropertyInfo info in array2){Console.Write(info.Name+" ");}MethodInfo[] array3 = type.GetMethods();//获取方法foreach (MethodInfo info in array3){Console.Write(info.Name+" ");}//通过type对象可以获取它对应的类的所有成员(public)MyClass my = new MyClass();Assembly assem =  my.GetType().Assembly;//通过类的type对象获取它所在的程序集 AssemblyConsole.WriteLine(assem.FullName);Type[] types = assem.GetTypes();foreach (var type in types)//遍历程序集中定义的类型  {Console.WriteLine(type);}Console.ReadKey();

特性

特性(attribute)是一种允许我们向程序的程序集增加元数据的语言结构。它是用于保存程序结构信息的某种特殊类型的类。

  1. 将应用了特性的程序结构叫做目标
  2. 设计用来获取和使用元数据的程序(对象浏览器)叫做特性的消费者
  3. NET预定了很多特性,我们也可以声明自定义特性
  • Obsolete特性

使用Obsolete特性将程序结构标注为过期的,并且在代码编译时,显示有用的警告信息

        [Obsolete("这个方法过时了,使用NewMethod代替")] //obsolete特性用来表示一个方法被弃用了static void OldMethod(){Console.WriteLine("Oldmethod");}static void NewMethod(){}
  • Conditional特性

Conditional特性允许我们包括或取消特定方法的所有调用。为方法声明应用Conditional特性并把编译符作为参数来使用。

#define DoTrace //如果不定义这个宏,就不会调用方法TraceMessageclass Program{[Conditional("DoTrace")] //其中的字符任写static void TraceMessage(string str){Console.WriteLine(str);}static void Main(){TraceMessage("Start of Main");Console.WriteLine("Doing work in Main.")TraceMessage("End of Main");}
}

还有一些特性和自定义特性,用的地方太少,等需要的时候再学习。

线程

只有一个前台线程在运行,应用程序的进程就在运行,如果多个前台线程在运行,但是Main方法结束了,应用程序的进程仍然是运行的,直到所有的前台线程完成其任务为止。

在默认情况下,用Thread类创建的线程是前台线程。线程池中的线程总是后台线程。

在用Thread类创建线程的时候,可以设置IsBackground属性,表示它是一个前台线程还是一个后台线程。

当所有的前台线程运行完毕,如果还有后台线程运行的话,所有的后台线程会被终止掉。

委托创建线程

 //一般我们会为比较耗时的操作 开启单独的线程去执行,比如下载操作static int Test(int i, string str){Console.WriteLine("测试线程" + i + str);Thread.Sleep(100);//让当亲线程休眠(暂停线程的执行) 单位msreturn 100;}static void Main(string[] args){   //在main线程中执行 一个线程里面语句的执行 是从上到下的//1,通过委托 开启一个线程Func<int, string, int> a = Test;//赋值一个委托函数IAsyncResult xiancheng1 = a.BeginInvoke(100, "循环检测", null, null);// 开启一个新的线程去执行 a所引用的方法 //IAsyncResult 可以取得当前线程的状态//可以认为线程是同时执行的(异步执行)Console.WriteLine("main");while (xiancheng1.IsCompleted == false)//如果当前线程没有执行完毕{Console.Write(".");Thread.Sleep(10); //控制子线程的检测频率}int res1 = a.EndInvoke(xiancheng1);//取得异步线程的返回值Console.WriteLine(res1);//检测线程结束IAsyncResult xiancheng2 = a.BeginInvoke(100, "等待方式检测", null, null);bool isend = xiancheng2.AsyncWaitHandle.WaitOne(1000);// 1000毫秒表示超时时间,如果等待了1000毫秒 线程还没有结束的话 那么这个方法会返回false //如果在1000毫秒以内线程结束了,那么这个方法会返回trueif (isend){int res2 = a.EndInvoke(xiancheng2);Console.WriteLine(res2);}//通过回调 检测线程结束//倒数第二个参数是一个委托类型的参数,表示回调函数,就是当线程结束的时候会调用这个委托指向的方法//倒数第一个参数用来给回调函数传递数据a.BeginInvoke(100, "回调检测", OnCallBack, a);a.BeginInvoke(100, "回调匿名检测", xiancheng3 =>{int res4 = a.EndInvoke(xiancheng3);//匿名函数可以直接访问外部变量Console.WriteLine(res4);}, null);Console.ReadKey();//定义的回调函数static void OnCallBack(IAsyncResult ar)//回调的参数固定IAsyncResult{Func<int, string, int> a = ar.AsyncState as Func<int, string, int>;//里氏转换int res3 = a.EndInvoke(ar);Console.WriteLine(res3);}

Thread创建线程

 static void DownloadFile(object filename){//Thread.CurrentThread.ManagedThreadId获取当前线程的IDConsole.WriteLine("开始下载:" + Thread.CurrentThread.ManagedThreadId + filename);Thread.Sleep(2000);Console.WriteLine("下载完成");}static void Main(string[] args){Thread t = new Thread(DownloadFile);t.IsBackground = true;//设置为后台线程 t.Start("xxx");Console.WriteLine("主线程");t.Join(); //当前线程睡眠,等待t线程执行完,然后继续运行下面的代码Console.ReadKey();MyThread my = new MyThread("xxx.bt","http://www.xxx.bbs");Thread t1 = new Thread(my.DownFile);//我们构造一个thread对象的时候,可以传递一个静态方法,也可以传递一个对象的普通方法t1.Start();t1.Abort();//终止这个线程的执行}

线程池

  //开启一个工作线程,参数一为函数,后面的参数是传入函数的参数ThreadPool.QueueUserWorkItem(DownloadFile,"xxx");

任务

 Task t = new Task(DownloadFile,"xxx");//创建任务t.Start();TaskFactory tf = new TaskFactory(); //创建任务工厂Task t1 = tf.StartNew(DownloadFile,"xxxx");

连续任务

        static void DoFirst(){Console.WriteLine("do  in task : " + Task.CurrentId);Thread.Sleep(3000);}static void DoSecond(Task t){Console.WriteLine("task " + t.Id + " finished.");Console.WriteLine("this task id is " + Task.CurrentId);Thread.Sleep(3000);}Task t1 = new Task(DoFirst);Task t2 = t1.ContinueWith(DoSecond);Task t3 = t1.ContinueWith(DoSecond);Task t4 = t2.ContinueWith(DoSecond);t1.Start();

任务层次结构

我们在一个任务中启动一个新的任务,相当于新的任务是当前任务的子任务,两个任务异步执行,如果父任务执行完了但是子任务没有执行完,它的状态会设置为WaitingForChildrenToComplete,只有子任务也执行完了,父任务的状态就变成RunToCompletion

        static void ParentTask(){Console.WriteLine("task id " + Task.CurrentId);var child = new Task(ChildTask);child.Start();Thread.Sleep(1000);Console.WriteLine("parent started child , parent end");}static void ChildTask(){Console.WriteLine("child");Thread.Sleep(5000);Console.WriteLine("child finished ");}var parent = new Task(ParentTask);parent.Start();Thread.Sleep(2000);Console.WriteLine(parent.Status);Thread.Sleep(4000);Console.WriteLine(parent.Status);Console.ReadKey();

锁是用来锁住对象的,被锁住的对象只有在当前线程解开后,才能被其他线程访问该对象

static void RaceCondition(object o ){StateObject state = o as StateObject;int i = 0;while(true){lock(state){ //锁住state对象state.ChangeState(i++);          }}
}

C#委托·特性·linq查询.线程相关推荐

  1. LINQ 查询表达式(C# 编程指南)

    LINQ 查询表达式(C# 编程指南) 语言集成查询 (LINQ) 是一组技术的名称,这些技术建立在将查询功能直接集成到 C# 语言(以及 Visual Basic 和可能的任何其他 .NET 语言) ...

  2. linq 查询的结果会开辟新的内存吗?

    一:背景 1. 讲故事 昨天群里有位朋友问:linq 查询的结果会开辟新的内存吗?如果开了,那是对原序列集里面元素的深拷贝还是仅仅拷贝其引用? 其实这个问题我觉得问的挺好,很多初学 C# 的朋友或多或 ...

  3. [译]如何在C#中调试LINQ查询

    LINQ是我在C#中最喜欢的功能之一.它让代码看起来更漂亮美观.我们得到了一个易于编写和理解的简洁函数式语法.好吧,至少我们可以使用LINQ方法的语法风格. LINQ很难进行调试.我们无法知道该查询内 ...

  4. linq查询不包含某个值的记录_【翻译】C#表达式中的动态查询

    当您使用LINQ来处理数据库时,这种体验是一种神奇的体验,对吗?你把数据库实体像一个普通的收集,使用Linq中像Where,Select或者 Take,这些简单的使用就能让代码可用了. 但是,让我们考 ...

  5. Entity Framework 6 Recipes 2nd Edition(13-6)译 - 自动编译的LINQ查询

    问题 你想为多次用到的查询提高性能,而且你不想添加额外的编码或配置. 解决方案 假设你有如Figure 13-8 所示的模型 Figure 13-8. A model with an Associat ...

  6. C#编程 LINQ查询

    LINQ查询表达式 约束 LINQ查询表达式必须以from子句开头,以select或group子句结束 关键字 from...in...:指定要查找的数据以及范围变量,多个from子句则表示从多个数据 ...

  7. 《C# 语言入门详解(刘铁锰) - 学习笔记 - Lambda表达 / Linq查询》

    Lambda表达 / LINQ查询 文章目录 Lambda表达 / LINQ查询 前言 一.Lambda表达式 二.LINQ查询 前言 Lambda表达式: 匿名方法.inline(内联)方法.(简化 ...

  8. Windows Phone本地数据库(SQLCE):11、使用LINQ查询数据库(翻译) (转)

    这是"windows phone mango本地数据库(sqlce)"系列短片文章的第十一篇. 为了让你开始在Windows Phone Mango中使用数据库,这一系列短片文章将 ...

  9. Linq查询语法(2)

    转:http://www.cnblogs.com/knowledgesea/p/3897665.html 1.简单linq查询 //1var ss = from r in db.Am_recProSc ...

最新文章

  1. 你那么追捧的springboot,到底替你做了什么?
  2. [转] MySQL主从复制(Master-Slave)与读写分离(MySQL-Proxy)实践
  3. c语言中continue在case中,C語言switch case 語句中能否使用continue 關鍵字?
  4. signature=8cc1e8491a741a9dc954b549013b75e5,基于小波的SAR影像纹理分析
  5. 倒计时 时间校准android,android倒计时器时间
  6. upstream directive is not allowed here in
  7. linux远程登录模拟输入输出重定向,从零开始学习Linux(三十三):Shell基础之输入输出重定向...
  8. 关于加域后win7、win8的C:\不能够新建文件,报0X0070522错误的解决方式
  9. linux的/dev内容介绍
  10. 软件基本功能测试用例,测试用例实例—常见功能测试点().docx
  11. 河流淹没分析_【专题归纳】关于河流地貌的知识点整理!附中国十二条著名江河名称的由来...
  12. 静态成员变量.xml
  13. 干货|看怎么肢解堆垛机!
  14. 智能dns调研及bind9搭建
  15. 泰拉瑞亚 服务器linux,泰拉瑞亚Linux主机打造指南
  16. dx12 龙书第十六章学习笔记 -- 实例化与视锥体剔除
  17. antares任务调度系统预研
  18. 无监督关键短语的生成问题博客02--extract.py的分析
  19. Ubuntu系统修改用户名
  20. rust画质怎么设置不卡顿_腐蚀游戏怎么提高帧数 Rust设置隐藏画质提高FPS教程

热门文章

  1. 让你的运维系统充满“诗意”
  2. linux 进程内存分析工具,Linux内存使用情况以及内存泄露分析之工具与方法
  3. 【js JavaScript 】js string 转 int 注意的问题小结 Number()和parseInt()区别
  4. 火力篮球游戏源码完整版--采用标准的游戏开发文档
  5. 致逝去的大学四年和工作一年后的自己
  6. 数组去重(驱虫)的两种方法
  7. 通过逆向学习软件设计(2)
  8. lol服务器位置峡谷之巅,lol英雄联盟峡谷之巅怎么进_峡谷之巅是什么_峡谷之巅报名需要什么段位...
  9. 南方都市报评论:我们为什么一定要学外语?
  10. 精美UI强大娱乐功能组合微信小程序源码下载,安装简单