C#基础进阶

观看C#高级教程进行学习。巩固基础,进阶学习。

1.委托

把方法当做参数来传递就是委托。委托的关键字是delegate。

 class Program
    {
        private delegate string GetString();
        static void Main(string[] args)
        {
        int x=40;
        GetString a = x.ToString;//方法签名
        string t = a();
        Console.WriteLine("{0}", t);
        Console.ReadKey();
        }
    }
委托获取X的String

Invoke方法也可以调用委托所引用的方法。a.Invoke();

Action委托 无返回值 void返回类型

       static void Print()
        {
            Console.WriteLine("www");

        }
        static void Main(string[] args)
        { 
            int x=100;
            Action a = Print;//Action是系统内置的一个委托类型,指向一个没有返回类型,没有参数的方法
            a.Invoke();
            Console.ReadKey();
        }
Action委托
      static void Print(int x)
        {
            Console.WriteLine("www");

        }
        static void Main(string[] args)
        { 
            int x=100;
            //Action a = Print;//Action是系统内置的一个委托类型,指向一个没有返回类型,没有参数的方法
            Action<int> a = Print;//定义一个委托类型,指向一个没有返回值,有一个int参数的方法。
            a.Invoke(x);
            Console.ReadKey();
        }
Action

多个参数也是可以的。Action<T,T,T> 最多可以16个参数。

Func委托

static int Print ()
        {
            return 1;
        }

        static int test(string str)
        {
            Console.WriteLine(str);
            return 1;
        }

        static void Main(string[] args)
        { 

            Func<int> a = Print;//泛型指定的是方法的返回值类型
            Func<string, int> b = test;//Func后面可以跟很多类型,最后一个类型是返回类型,前面都是参数类型,参数类型必须和方法参数对应。
                                       //返回值类型必须有一个。
            Console.WriteLine(a());
            b("11");
            Console.ReadKey();
        }
Func委托

Func委托依然支持16个参数,但必须有返回类型值。多个参数时,返回类型写最后一个。

Action理解为动作委托,执行,可加参数。Func比较全面。

这两种方法不需要自己定义,直接用就好了,比较方便。

多播委托->使用+=来进行追加委托引用。

Func<int, int, int> a = delegate(int add1, int add2)
            {
                return add1 + add2;
            };//匿名方法本质是一个方法,任何使用委托的地方都可以使用匿名方法。
匿名方法
 Func<int, int, int> plus = (add1, add2) =>//Lambda参数不需要声明类型
            {

                return add1 + add2;
            };
            Console.WriteLine(plus(1, 1));
            Console.ReadKey();
Lambda表达式

Lambda表达式可以代替匿名方法。

2.事件

 事件是受限制的委托。public event delegate Mydelegate;

3.LINQ查询

ModelInfo model = (from l in listModels
                               where l.modelName == strModelFunc && l.modelId == strModelID && l.line == strLine && strStation == l.station
                               select new ModelInfo
                               {
                                   sid = l.sid,
                                   modelName = l.modelName,
                                   line = l.line,
                                   csname = l.csname,
                                   factory = l.factory,
                                   modelId = l.modelId,
                                   station = l.station
                               }).FirstOrDefault();
LINQ NEW对象

背景一个名字 功夫 等级表 一个功夫名和伤害表

var res= from m in List//from 设置查询的集合
              where m.Level>8
              select m;//选中m 也可以是m中的属性
LINQ查询
var res=list.where(a=>a.level>8)
扩展方法写法
var res= from m in alist
              from n in blist 
             while m.kongfu=n.name &&n.power>90//连接限制条件 功夫名字相等,杀伤力大于90
             select m //获取人物(伤害大于90)
             select  new{master=m,kongfu=k}//获取全部的数据(在限制条件下)
LINQ联合查询

select最后选择的是获取什么数据

排序 orderby 降序 descending

多个字段排序 orderby m.level ,m.age //当第一个字段相同,按第二个来。

var res=from m in alist
             join k in blist on m.kongfu equals k.Name
             where k.power>90
             select new {master=m,kongfu =k};//两表连接
LINQ JOIN ON

方法写法有SKIP 跳页 ,两种写法可以混合使用。

4.反射和特性

程序及其类型的数据称为元数据。

查看本身或其他程序集的元数据的行为就叫反射。

 MyClass myclass = new MyClass();
            Type type=myclass.GetType();//获取类的type对象
            Console.WriteLine(type.Name);//获取类名
            Console.WriteLine(type.Namespace);//获取命名空间
            Console.WriteLine(type.Assembly);//获取集合类
            FieldInfo[] array=type.GetFields();//只能获取共有字段
            foreach (var m in array)
            {
                Console.WriteLine(m.Name);
            }
            PropertyInfo[] array2 = type.GetProperties();//获取属性
            foreach (var n in array2)
            {
                Console.WriteLine(n.Name);
            }
            MethodInfo[] array3 = type.GetMethods();//获取方法
            foreach (var k in array3)
            {
                Console.WriteLine(k.Name);
            }
            Console.ReadKey();
Type对象
 MyClass myclass = new MyClass();
            Assembly assem = myclass.GetType().Assembly;//通过类的type对象获取所在程序集Assembly
            Console.WriteLine(assem.FullName);
            Type[] type=assem.GetTypes();
            foreach (var k in type)
            {
                Console.WriteLine(k.Name);
            }
            Console.ReadKey();
Assembly对象

特性:向程序的程序集增加元数据的语言结构。

[Obsolete("该方法弃用",false)]//表示该方法已经弃用,第一个参数表示给予的提示信息,第二个参数表示是否显示错误,true会报错,false会提示警告.
        static void OldMethod() { 
        
        }
Obsalete特性
#define IsTest//定义一个宏
 [Conditional("IsTest")]
        static void OldMethod()
        {
            Console.WriteLine("111111");

        }
//在引用前面定义宏,使用Conditional特性,如果不需要使用该方法,注释宏定义即可。
Conditional特性

 5.进程和线程

进程理解为一个应用程序,线程理解为应用程序下的任务。

Action a=Test;//委托a指向方法Test()
a.BeginInvoke(null,null);//开启线程去执行
异步委托BeginInvoke
Func<int,string,int> a= Test;
IAsyncResult ar=a.BeginInvoke(100,“sky”,OnCallBack,a);
//倒数第二个参数表示一个委托类型的参数,表示回调函数,如果没有回调可以写Null,回调函数就是异步结束了会去调用这个委托指向的方法,倒数第一个参数表示用来给回调函数传递数据。
static void OnCallBack(IAsyncResult ar)
{
Func<int,string,int> a=ar.AsncState as Func<int,string,int>;
 int res=a.EndInvoke(ar);
}
回调函数

线程

static void DownloadFile()//无参
{
}
Thread t= new Thread(DownloadFile);//创建Thread对象,但没有启动
t.Start()//启动
 
static void DownloadFile(object Filename)//带参数,只能是objec对象
{
}
Thread t= new Thread(DownloadFile);//创建Thread对象,但没有启动
t.Start("1111")//启动  参数在start中传入
 
Thread

前台线程和后台线程

前台线程,前台线程当Main方法结束了,依然在运行,直到前台线程完成其任务为止。

后台线程,当Main结束了,后台线程随之结束。

IsBackgroud设置。

线程池

 static void ThreadMethod(object state)//线程池调用的方法默认带有Object参数
        {
            Console.WriteLine("线程开始"+Thread.CurrentThread.ManagedThreadId);
            Thread.Sleep(2000);
            Console.WriteLine("线程结束");
        }
static void Main(string[] args)
        {
             ThreadPool.QueueUserWorkItem(ThreadMethod);//开启一个工作线程 线程池默认是后台线程 不能修改为前台线程 只能用于比较短的线程
            ThreadPool.QueueUserWorkItem(ThreadMethod);
            ThreadPool.QueueUserWorkItem(ThreadMethod);
            ThreadPool.QueueUserWorkItem(ThreadMethod);
            ThreadPool.QueueUserWorkItem(ThreadMethod);
            Console.ReadKey();

        }//多个线程的情况,例如第一秒跑第一个 第二秒跑第二个
线程池

原文地址:https://www.cnblogs.com/cdjbolg/p/11896775.html