C#高级语法(一些基础使用的例子的实现)

一、扩展方法

在这里插入图片描述
在这里插入图片描述

定义:

using System;

namespace WindowsFormsApp3
{
    public static class A
    {
        public static void Boy(this int x)
        {
            Console.WriteLine(x);
        }
    }
}

调用:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApp3
{
    internal static class Program
    {
        static void Main()
        {
            3.Boy();
            A.Boy(9);
            while (true) ;
        }


    }
}

二、匿名类型

在这里插入图片描述

简单的使用:

            //创建使用匿名类型对象
            var person = new { Name = "L", Age = 17 };
            Console.WriteLine($"{ person.Name},{person.Age}");

            //动态类型处理匿名类型对象
            //缺点:属性名写错了,也不会报错,运行时出错
            dynamic GetPerson()
            {
                return new { Name = "TY", Age = 46 };
            }
            dynamic x = GetPerson();
            Console.WriteLine($"{ x.Name},{x.Age}");

            //解决
            //指定类型接受匿名类型对象
            //这个技巧只有在同一个程序集中的代码才有效
            var cup = new { Name = "", Age = 0 };
            cup = GetPerson();
            Console.WriteLine($"{ cup.Name},{cup.Age}");

通过反射获取匿名类型数据项(测试匿名类型作参数)

using System;
using System.Reflection;
using System.Threading;

namespace ConsoleApp1
{
    internal class Program
    {
        public class Test
        {
            public static void One(object obj)
            {
                Type t =obj.GetType();
                PropertyInfo pName = t.GetProperty("Name");
                PropertyInfo pAge = t.GetProperty("Age");

                Console.WriteLine($"匿名类型:{t.Name}");
                Console.WriteLine($"Name:{pName?.GetValue(obj)},Age:{pAge?.GetValue(obj)}");
            }
        }

        static  void Main(string[] args)
        {
            Test.One(new { Name = "abc", Age = "123" });
            
            while(true) { 
                
                Thread.Sleep(1000);
            }
            return;
        }
    }
}

linq支持对匿名对象集合的查询处理

using System;
using System.Linq;
using System.Threading;

namespace ConsoleApp1
{
    internal class Program
    {
        static  void Main(string[] args)
        {
            //linq支持对匿名对象集合的查询处理
            var people = new[]
            {
                new{Name = "a",Age=30},
                new{Name = "dh",Age=32},
                new{Name = "fl",Age=35},
            };

            var query = from p in people
                        where p.Age > 30
                        select p;

            foreach(var person in query)
            {
                Console.WriteLine($"Name:{person.Name},Age:{person.Age}");
            }
            
            while(true) { 
                
                Thread.Sleep(1000);
            }
            return;
        }
    }
}

//使用 LINQ 进行联合查询,查询学生信息以及对应的班级信息

using System;
using System.Linq;
using System.Threading;

namespace ConsoleApp1
{
    internal class Program
    {
        static  void Main(string[] args)
        {
            var studentList = new[]
            {
                new{Name="a",Age=33 ,Gender = "男",ClassId=1},
                new{Name="b",Age=33 ,Gender = "男",ClassId=1},
                new{Name="c",Age=33 ,Gender = "男",ClassId=1},
                new{Name="d",Age=33 ,Gender = "男",ClassId=1},
                new{Name="e",Age=33 ,Gender = "男",ClassId=1},
                new{Name="f",Age=33 ,Gender = "男",ClassId=3},
                new{Name="g",Age=33 ,Gender = "男",ClassId=3},
                new{Name="h",Age=33 ,Gender = "男",ClassId=3},
                new{Name="i",Age=33 ,Gender = "男",ClassId=3},
                new{Name="j",Age=33 ,Gender = "男",ClassId=2},
                new{Name="k",Age=33 ,Gender = "男",ClassId=2},
                new{Name="l",Age=33 ,Gender = "男",ClassId=2},
            };

            var classList = new[]
            {
                new{ClassName="A",Teacher="Aer",Id=1},
                new{ClassName="B",Teacher="Ber",Id=2},
                new{ClassName="C",Teacher="Cer",Id=3},
            };


            //使用 LINQ 进行联合查询,查询学生信息以及对应的班级信息
            var result = from s in studentList
                         join c in classList on s.ClassId equals c.Id
                         select new
                         {
                             学生姓名 = s.Name,
                             年龄 = s.Age,
                             性别 = s.Gender,
                             班级名称 = c.ClassName,
                             班级教师 = c.Teacher
                         };

            //输出查询结果
            foreach(var item in result)
            {
                Console.WriteLine($"学生姓名:{item.学生姓名},年龄:{item.年龄},性别:{item.性别},班级名称:{item.班级名称},班级教师:{item.班级教师}");
            }
            
            while(true) { 
                
                Thread.Sleep(1000);
            }
            return;
        }
    }
}

简写:自动以属性为名称

using System;
using System.Linq;
using System.Threading;

namespace ConsoleApp1
{
    internal class Program
    {
        static  void Main(string[] args)
        {
            var studentList = new[]
            {
                new{Name="a",Age=33 ,Gender = "男",Id=1},
                new{Name="f",Age=33 ,Gender = "男",Id=3},
                new{Name="j",Age=33 ,Gender = "男",Id=2},

            };

            //使用 LINQ 进行联合查询,查询学生信息以及对应的班级信息
            //这里没写属性名,自动以属性为名称
            var result = from s in studentList
                         select new
                         {
                             s.Id,
                             s.Name,
                         };

            //输出查询结果
            foreach(var item in result)
            {
                Console.WriteLine($"学生ID:{item.Id},学生姓名:{item.Name}");
            }
            
            while(true) { 
                
                Thread.Sleep(1000);
            }
            return;
        }
    }
}

三、元组

使用元组交互元素

            string str1 = "aaa";
            string str2 = "BBB";
            Console.WriteLine(str1+" : "+str2);
            (str1, str2) = (str2, str1);
            Console.WriteLine(str1 + " : " + str2);

定义与使用:

使用元组(),将多个数据元素构成一个轻型数据结构
(string,int) x = new ValueTuple<string,int>(“Bob”,25);
(string,int) x = ValueTuple.Create(“Bob”,25);

using System;

namespace ConsoleApp2
{
    internal class Program
    {
        static void Main(string[] args)
        {
            //使用元组(),将多个数据元素构成一个轻型数据结构
            //(string, int) x = new ValueTuple<string, int>("Bob", 25);
            //(string, int) x = ValueTuple.Create("Bob", 25);
            (string, int) x = ("aaa", 99);
            var y = ("bbb", 19);
            Console.WriteLine($"姓名:{x.Item1},年龄:{x.Item2}");
        }
    }
}

使用字段名

using System;

namespace ConsoleApp2
{
    internal class Program
    {
        static void Main(string[] args)
        {
            //使用命名字段
            var x = (name: "asd", age: 99);
            Console.WriteLine($"姓名:{x.name},\t年龄:{x.age}");

            (string name, int age) y = ("KL", 12);
            Console.WriteLine($"姓名:{y.name},\t年龄:{y.age}");

            while (true) ;
        }
    }
}

元组的解构 与 弃元

using System;

namespace ConsoleApp2
{
    internal class Program
    {
        static void Main(string[] args)
        {
            //元组的解构
            var (name, age) = ("qaz", 10);
            Console.WriteLine($"姓名:{name},年龄:{age}");

            //弃元 就是放弃不需要的元素
            var tuple = (1, "a", 3.12);
            var(_,letter,_)=tuple;
            Console.WriteLine(letter);

            while (true) ;
        }
    }
}

元组作为入参和返回值的用法

using System;

namespace ConsoleApp2
{
    internal class Program
    {
        //元组作为参数
        void ProcessTuple((string Name,int Age) person)
        {
            Console.WriteLine($"Name:{person.Name},Age:{person.Age}");
        }

        //元组作为返回类型
        (int Sum,int Product)GetSumAndProduct(int a,int b)
        {
            return (a + b, a * b);
        }

        static void Main(string[] args)
        {
            Program program = new Program();
            //元组作为参数
            program.ProcessTuple(("A", 25));

            //元组作为返回类型
            var result = program.GetSumAndProduct(2, 3);
            Console.WriteLine($"和:{result.Sum},积{result.Product}");

            while (true) ;
        }
    }
}

元组类型支持相等运算符 == != ,比较的是各个元素

using System;

namespace ConsoleApp2
{
    internal class Program
    {
        static void Main(string[] args)
        {
            //元组类型支持相等运算符 == != ,比较的是各个元素
            var data = (2, 2.3);
            if ((2, 2.2) == data) 
            {
                Console.WriteLine("相等");
            }
            else
            {
                Console.WriteLine("不相等");
            }

            while (true) ;
        }
    }
}

LINQ查询

using System;
using System.Linq;

namespace ConsoleApp2
{
    internal class Program
    {
        static void Main(string[] args)
        {
            var studentList = new[] {
                (Name: "af",Age: 99,Gender: "男",ClassId:1),
                (Name: "af",Age: 99,Gender: "男",ClassId:2),
                (Name: "af",Age: 99,Gender: "男",ClassId:2),
                (Name: "af",Age: 99,Gender: "男",ClassId:2),
                (Name: "af",Age: 99,Gender: "男",ClassId:3)
            };
            var classList = new[] {
                (ClassName: "YU1",Teacher: "LL1",Id:1),
                (ClassName: "YU2",Teacher: "LL2",Id:2),
                (ClassName: "YU3",Teacher: "LL3",Id:3)
            };
            //使用 LINQ 进行联合查询 学生信息以及对应的班级信息
            var result = from s in studentList
                         join c in classList on s.ClassId equals c.Id
                         select (
                             学生姓名: s.Name,
                             年龄: s.Age,
                             性别: s.Gender,
                             班级名: c.ClassName,
                             班级教师: c.Teacher
                         );
            //输出查询结果
            foreach(var item in result )
            {
                Console.WriteLine($"学生姓名:{item.学生姓名},年龄{item.年龄}:,性别:{item.性别},班级名称:{item.班级名},班级教师:{item.班级教师}");
            }
            while (true) ;
        }
    }
}

元组可以修改,匿名对象不可以

using System;
using System.Linq;

namespace ConsoleApp2
{
    internal class Program
    {
        static void Main(string[] args)
        {
            //元组可以修改,匿名对象不可以
            var p = (name: "ABD", age: 69);
            p.name = "LO";
            Console.WriteLine(p);
            while (true) ;
        }
    }
}

四、GDI

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

五、特性与反射

特性的说明:

等价于 java 中的 注解;作用就是在 类、方法、属性上加个钩子,作为标记或调用的入口

特性,通常是放到类、属性、方法上面,对其进行一个说明;信息的扩展

特性的使用:
必须继承 Atrribute,然后可以添加属性、方法等
使用中括号 加载其他类或方法的上面

反射:

c中 内存可访问单位可以是 指针的步长
更高级的一些语言 没有指针 又想更自由的访问 比类更小的地方(如:类里的 方法、属性)
,可以把他们叫元对象,拿到这些元对象的技术,就叫做反射

反射可以做到的事情:
动态创建对象:根据字符串名称创建类型的新实例。
获取类型信息:查询类型的名字、命名空间、基类、接口等。
调用方法:调用类型的方法,即使这些方法是私有的。
访问字段和属性:读取和设置字段或属性的值。

例子 1(用反射抓取有指定特性的类或方法):

using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Windows.Forms;

namespace MVCFormApp
{
    public partial class Form1 : Form
    {
        List<Type> heroTypes;
        public Form1()
        {
            InitializeComponent();
        }


        private void 人物_Click(object sender, EventArgs e)
        {
            //加载所有人物
            heroTypes = Assembly.GetExecutingAssembly().GetTypes()
                .Where(t=>t.GetCustomAttributes(typeof(HeroAttribute),false).Any())
                .ToList();
            //打印
            foreach(Type t in heroTypes)
            {
                Console.WriteLine(t.Name);
            }
        }

        private void 行为_Click(object sender, EventArgs e)
        {
            for (int i = 0;i < heroTypes.Count; ++i){
                //创建对象
                var selectedHeroType = heroTypes[i];
                object hero = Activator.CreateInstance(selectedHeroType);

               //获取方法
                var skillMethods = selectedHeroType.GetMethods()
                    .Where(m => m.GetCustomAttributes(typeof(SkillAttribute), false).Any())
                    .ToList();

                //执行方法
                foreach(MethodInfo mi in skillMethods)
                {
                    mi.Invoke(hero, null);
                }


            }
        }
    }

    //定义标签
    public class HeroAttribute : Attribute { }
    public class SkillAttribute : Attribute { }

    [HeroAttribute]
    class Person1
    {
        [SkillAttribute]
        public void A()
        {
            Console.WriteLine("HHHHHHH1");
        }
        [SkillAttribute]
        public void AA()
        {
            Console.WriteLine("HHHHHHH2");
        }
        [SkillAttribute]
        public void AAA()
        {
            Console.WriteLine("HHHHHHH3");
        }
    }
    [HeroAttribute]
    class Person2
    {
        [SkillAttribute]
        private void B()
        {
            Console.WriteLine("JJJJJJJ");
        }
    }
    [HeroAttribute]
    class Person3
    {
        [SkillAttribute]
        private void C()
        {
            Console.WriteLine("KKKKKKKKK");
        }
    }
}

例子 2 (用反射拿到绑定 特性 的类 、类里的属性、类里的方法)

using System;
using System.Linq;

namespace ConsoleApp1
{
    //定义---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    //一个自定义的类
    //特性的使用说明     可以写在类上             可以写在方法上            可以写在属性上        使用可以放多个特性     是否继承到子类
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = true, Inherited = true)]

    public class MyCustomAttribute : Attribute
    {
        public MyCustomAttribute(int x)
        {
            propert1 = x;
        }

        public int propert1 { get; set; }

        public int Method1()
        {
            Console.WriteLine($"this is Method1,propert1:{propert1}");
            return 200;
        }
    }

    //可以继承
    public class MyCustomAttribute2 : MyCustomAttribute
    {
        public MyCustomAttribute2(int x = 0) : base(x)
        {

        }
    }
    //使用---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    [MyCustomAttribute(1)]
    [MyCustomAttribute(2)]
    [MyCustomAttribute2]
    public class A:Object
    {
        //增加标记
        [MyCustomAttribute2]
        public int propert1 { get; set; }
        [MyCustomAttribute2]
        public int propert2 { get; set; }
        [MyCustomAttribute2]
        public int propert3 { get; set; }
        [MyCustomAttribute2]
        public int propert4 { get; set; }
        [MyCustomAttribute2]
        public int propert5 { get; set; }



        //注入信息
        [MyCustomAttribute(10)]
        public int Method1()
        {
            Console.WriteLine("this is Method1");
            return 1;
        }
        [MyCustomAttribute(20)]
        public int Method2()
        {
            Console.WriteLine("this is Method2");
            return 2;
        }
        [MyCustomAttribute(30)]
        public int Method3()
        {
            Console.WriteLine("this is Method3");
            return 3;
        }
    }

    internal class Program
    {
        

        static void Main(string[] args) 
        {
            Console.WriteLine();
            Console.WriteLine("抓取类上的特性----------------------------------------------");
            Test001();

            Console.WriteLine();
            Console.WriteLine("抓取属性上的特性----------------------------------------------");
            Test002();

            Console.WriteLine();
            Console.WriteLine("抓取方法上的特性----------------------------------------------");
            Test003();

            //暂停
            Console.ReadLine();
        }

        //获取类上的自定义特性
        public static void Test001()
        {
            //获取类的类型
            Type type = typeof(A);
            
            //检查指定的类上有无 这个自定义的特性
            if (type.IsDefined(typeof(MyCustomAttribute), true))
            {
                //把特性取出来
                var myCusteomAttrivutes = type.GetCustomAttributes(typeof(MyCustomAttribute), true);
                //遍历所有特性
                foreach (var item in myCusteomAttrivutes)
                {
                    //对拿到的特性 类,进行操作,就想平常的类一样
                    var m = (MyCustomAttribute)item;
                    m.Method1();
                    m.propert1 = 300;
                    m.Method1();
                }
            }
        }

        //获取类中的属性上的特性
        public static void Test002()
        {
            //获取类的类型
            Type classType = typeof(A);
            //拿到这个类的所有属性
            var properties = classType.GetProperties();

            //遍历所有取出来的属性
            foreach(var property in properties)
            {
                //检查这个属性上有没有指定的特性
                if(property.IsDefined(typeof(MyCustomAttribute), true)){
                    //把属性上的特性取出来
                    var mCAs = property.GetCustomAttributes(typeof(MyCustomAttribute), true);
                    Console.WriteLine(property.Name + "-----");//打印下变量 的名字
                    foreach (var mCA in mCAs)
                    {
                        //对出来的 特性类进行操作
                        ((MyCustomAttribute)mCA).Method1();
                    }
                }
            }
        }

        //获取类里的方法上的特性
        public static void Test003()
        {
            //获取类的类型
            Type classType = typeof(A);
            //拿到这个类的所有方法
            var methods = classType.GetMethods();

            //遍历所有取出来的方法
            foreach (var method in methods)
            {
                //检查这个方法上有没有指定的特性
                if (method.IsDefined(typeof(MyCustomAttribute), true))
                {
                    //把方法上的特性取出来
                    var mCAs = method.GetCustomAttributes(typeof(MyCustomAttribute), true);
                    Console.WriteLine(method.Name + "-----");//打印下方法 的名字
                    foreach (var mCA in mCAs)
                    {
                        //对出来的 特性类进行操作
                        ((MyCustomAttribute)mCA).Method1();
                    }
                }
            }
        }
    }
}

用反射拿到类里的私有/静态 属性、方法

using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Windows.Forms;

namespace MVCFormApp
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            TestFunc();
        }
        private void TestFunc()
        {
            MyClass obj = new MyClass();
            Type type = typeof(MyClass);

            BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic;
            FieldInfo fieldInfo = type.GetField("myField",flags);
            fieldInfo?.SetValue(obj, "123");
            Console.WriteLine(fieldInfo?.GetValue(obj));

            PropertyInfo propertyInfo = type.GetProperty("myProperty", flags);
            Console.WriteLine(propertyInfo?.GetValue(obj));
            propertyInfo?.SetValue(obj, "重置的私有属性");
            Console.WriteLine(propertyInfo?.GetValue(obj));

            MethodInfo method = type.GetMethod("FunA", flags);
            method?.Invoke(obj, null);

            flags = BindingFlags.Static | BindingFlags.NonPublic;

            fieldInfo = type.GetField("sField", flags);
            Console.WriteLine(fieldInfo?.GetValue(null));

            method = type.GetMethod("FunB", flags);
            method?.Invoke(obj, null);
            method?.Invoke(null,null);
        }
    }

    class MyClass
    {
        private string myField = "私有字段";
        private static string sField = "静态私有字段";
        private string myProperty { get; set; } = "私有属性";
        private void FunA()
        {
            Console.WriteLine("私有方法执行.");
        }
        private static void FunB()
        {
            Console.WriteLine("静态私有方法执行.");
        }
    }
}

用反射、接口、xml里的 字符串 跨库调用里的接口,实现解耦

在这里插入图片描述
reflection

ClassSon.cs------------------------------------------------------

namespace Reflection
{
    internal class ClassSon : Interface1
    {
        //void say()
        //{
        //    Console.WriteLine("I am Son1");
        //}
        public void say()
        {

            Console.WriteLine("I am son1");
        }
    }
}
-------------------------------------------------------------------

Interface1.cs------------------------------------------------------

namespace Reflection
{
    internal interface Interface1
    {
        void say();
    }
}
----------------------------------------------------------------

Program.cs------------------------------------------------------
using System.Reflection;
using System.Configuration;
using ClassLibrary2;

Console.WriteLine("Hello, World!");
//Test001();
Test002();
Console.ReadLine();

//调用同一程序集的接口 (Load)
static void Test001()
{
    Reflection.Interface1 interface1 = (Reflection.Interface1)Assembly.Load("Reflection").CreateInstance("Reflection.ClassSon");
    interface1.say();

}

//调用其他程序集接口 (LoadFrom)
static void Test002()
{
    string assName = ConfigurationManager.AppSettings["assName"];
    string className = ConfigurationManager.AppSettings["className"];
    ClassLibrary2.Interface1 interface1 = (ClassLibrary2.Interface1)Assembly.LoadFrom(assName).CreateInstance(className);
    interface1.say();
}
------------------------------------------------------

classLibrary1

Class1.cs-------------------------------------------------------------------
namespace ClassLibrary1
{
    public class Class1 : Interface1
    {
        public void say()
        {
            Console.WriteLine("I am Class1");
        }
    }
}
--------------------------------------------------------------------------------

Interface1.cs-------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ClassLibrary1
{
    public interface Interface1
    {
        void say();
    }
}

--------------------------------------------------------------------------------

classLibrary2

Class1.cs-------------------------------------------------------------------
namespace ClassLibrary2
{
    public class Class1 : Interface1
    {
        public void say()
        {
            Console.WriteLine("I am Class2");
        }
    }
}
--------------------------------------------------------------------------------

Interface.cs-------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ClassLibrary2
{
    public interface Interface1
    {
        void say();
    }
}
--------------------------------------------------------------------------------

官方提供的特性 的使用:Obsolete 、Serializable

对 弃用说明类(Obsolete)的 使用

using System;

namespace ConsoleApp1
{
    internal class Program
    {
        static void Main(string[] args)
        {
            ClassA classA = new ClassA();
            classA.a = 1;
            classA.b = 1;
            classA.method_a();
            classA.method_b();
        }
        [Obsolete("该类已经过时,请使用 ClassB 类")]
        class ClassA
        {
            [Obsolete("该属性已经过时,请使用属性 b")]
            public int a {  get; set; }
            public int b { get; set; }
            [Obsolete("该方法已经过时,请使用 method_b 方法")]
            public void method_a()
            {
                Console.WriteLine("method_a");
            }
            public void method_b()
            {
                Console.WriteLine("method_b");
            }
        }
        class ClassB{}


    }
}

对 序列化特性(Serializable)的 使用

using System;

namespace ConsoleApp1
{
    internal class Program
    {
        static void Main(string[] args)
        {
        }
        [Serializable]
        class ClassA
        {
            public int a {  get; set; }
            public int b { get; set; }
            public ClassB classB;
            public void method_a()
            {
                Console.WriteLine("method_a");
            }
            public void method_b()
            {
                Console.WriteLine("method_b");
            }
        }
        [Serializable]
        class ClassB{
            public string c {  get; set; }
        }
    }
}

六、泛型

使用举例(泛型类、泛型参数、泛型返回值)

using System;

namespace ConsoleApp1
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
            MyStack<int> stack = new MyStack<int>(10);
            stack.Push(1);
            stack.Push(2);
            stack.Push(3);
            stack.Push(4);
            stack.Push(5);
            stack.Push(6);
            stack.Push(7);
            stack.Push(8);
            stack.Push(9);
            stack.Push(0);

            Console.WriteLine(stack.Pop());
            Console.WriteLine(stack.Pop());
            Console.WriteLine(stack.Pop());
            Console.WriteLine(stack.Pop());
            Console.WriteLine(stack.Pop());
            Console.WriteLine(stack.Pop());
            Console.WriteLine(stack.Pop());
            Console.WriteLine(stack.Pop());
            Console.WriteLine(stack.Pop());
            Console.WriteLine(stack.Pop());
        }
    }

    //出入栈泛型
    public class MyStack<T>
    {
        //泛型数组
        private T[] stack;

        //元素位置
        private int stackIndex;

        //数据容量
        private int size;

        public MyStack(int size)
        {
            this.size = size;
            this.stack = new T[size];
            this.stackIndex = -1;//入栈开始是0,每次先加1
        }
        //元素入栈
        public void Push(T item)
        {
            if(this.stackIndex >= this.size)
                Console.WriteLine("栈空间已满");
            else
            {
                this.stackIndex++;
                this.stack[stackIndex] = item;
            }
        }
        //元素出栈
        public T Pop()
        {
            T data = this.stack[stackIndex];//后进先出
            stackIndex--;//元素出栈后,下一个要出栈的元素索引
            return data;
        }
    }
}

泛型函数

        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
            Console.WriteLine(function<int>(100));
        }

        static T1 function<T1>(T1 a1)
        {
            return a1;
        }
    }
-------------------------------------------------------------------------------
        public T add<T,T1,T2>(T1 a,T2 b)where T : struct, T1, T2
        {
            dynamic a1 = a;
            dynamic b1 = b;

            return a1 + b1;
        }

用 default 来完成 模板类的 泛型变量 的初始化

    public class MyGenericClass<T1, T2>
    {
        private T1 data1;
        private T2 data2;
        public MyGenericClass()
        {
            //data1 = new T1();
            //data1 = null;       //因为 T1 类型不是引用类型,需要用不了 new 和 null
            
            //但是可以使用 default 来完成初始化
            data1 = default(T1);
            data2 = default(T2);
        }
    }

泛型约束

    public class MyGenericClass<T1, T2, T3>
        where T1 : struct   //T1:表示值类型
        where T2 : class    //T2:表示引用类型
        where T3 : new()    //T3:表示一个类中,必须有一个无参的构造方法,这个约束必须放到最后
                            //其他还有:基类类型、接口类型。。。
    {
        public List<T2> CourseList { get; set; }
        public T3 Publisher { get; set; }
        public MyGenericClass()
        {
            this.CourseList = new List<T2>();
            Publisher = new T3();
        }
    }

dynamic 动态类型的使用

        List<string> CourceList=new List<string>(); 
        public T2 BuyCourse<T1,T2>(T1 index)
        {
            dynamic _index = index; //dynamic是在运行的时候解析对象类型,编译阶段不解析
            return CourceList[_index];
        }

七、委托、匿名方法、Lambda表达式

委托与事件的区别

委托-----函数指针
具体的,就是可以对函数指针的封装,加了个+=的运算符重载
就和函数指针的一个list了

using System;

namespace ConsoleApp1
{
    internal class Program
    {
        static void Main(string[] args)
        {
            new A().Test();
            Console.ReadLine();
        }
        class A
        {
            public void Test() 
            { 
                B b = new B();
                //[4] 关联委托方法
                //b.didi += execute;
                b.didi = execute;
                b.test();
            }

            //[2] 方法编写
            void execute()
            {
                Console.WriteLine("execute...");
            }
        }
        class B
        {
            //[1] 声明委托
            public delegate void A();
            
            //[3] 创建委托方法
            public A didi;

            public void test()
            {
                //[5] 调用
                didi.Invoke();
                didi();
            }
        }
    }
}

事件,对委托又进行了一次封装
就是说,事件没有 event = null;的这种操作;没有 event.Invoke() 的操作
在这里插入图片描述

委托 -> 匿名方法 -> Lambda表达式

例子1:

using System;

namespace ConsoleApp1
{
    internal class Program
    {
        static void Main(string[] args)
        {
            new A().Test();
            Console.ReadLine();
        }
        class A
        {
            //委托
            delegate void myDelegate();

            public void Test()
            {
                //1、用方法名赋值
                myDelegate one = execute;
                one();
                //2、匿名方法
                myDelegate two = delegate () { Console.WriteLine("匿名方法"); };
                two.Invoke();
                //3、Lambad表达式
                myDelegate three = () => { Console.WriteLine("Lambad表达式"); };
                three();
            }

            //[2] 方法编写
            void execute()
            {
                Console.WriteLine("有名字的方法");
            }
        }

    }
}

例子2:

/*
 *  委托的几种赋值方式
 */

using System;

namespace ConsoleApp1
{
    internal class Program
    {


        static void Main(string[] args)
        {
            Test1(); 
            Test2();
            Test3();

            Console.ReadLine();
        }
        //--------------------------------------------------------------------------
        //用函数名 赋值 委托
        public static void Test1()
        {
            //定义委托变量
            Func<int, int, int> cal = Method;
            //使用委托变量
            int result = cal(10, 15);
            Console.WriteLine(result);
        }

        public static int Method(int a,int b)
        {
            return a + b;
        }

        //--------------------------------------------------------------------------
        //用 delegate 定义的匿名方法 赋值 委托
        public static void Test2()
        {
            //定义委托变量
            Func<int, int, int> cal = delegate (int a, int b)
            {
                return a + b;
            };
            //使用委托变量
            int result = cal(10, 15);
            Console.WriteLine(result);
        }
        //--------------------------------------------------------------------------
        //用 Lambad表达式 赋值 委托
        public static void Test3()
        {
            //定义委托变量
            Func<int, int, int> cal = (int a, int b) =>
            {
                return a + b;
            };
            //使用委托变量
            int result = cal(10, 15);
            Console.WriteLine(result);
        }
    }
}

泛型委托与Action、Func

自定义的泛型委托:

using System;

namespace ConsoleApp1
{
    internal class Program
    {
        static void Main(string[] args)
        {
            new A().Test();
            Console.ReadLine();
        }
        class A
        {
            //自定义委托
            delegate T myDelegate<T>(T a,T b);

            public void Test()
            {
                //自定义委托
                myDelegate<int> one = (int a,int b) => { return a + b; };
                Console.WriteLine(one(1,2)); 

                //Action的使用
                Action<int,int> two = (int a,int b) => { Console.WriteLine(  $"{a},{b}"); };
                two(2, 3);

                //Func的使用
                Func<int, int, int> three = (int a, int b) => { return a + b; };
                three.Invoke(10, 200);            
            }

            //[2] 方法编写
            void execute()
            {
                Console.WriteLine("有名字的方法");
            }
        }
    }
}

八、多线程(Thread)

Thread的API (之前的版本,现在用 Task)

在这里插入图片描述

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        private Thread thread = null;    //线程
        private int counter = 0;                        //计数器
        //
        private ManualResetEvent manualResetEvent = new ManualResetEvent(true);

        public Form1()
        {
            InitializeComponent();
        }
        //启动
        private void button1_Click(object sender, EventArgs e)
        {
            thread = new Thread(() =>
            {
                while (true)
                {
                    try
                    {
                        Thread.Sleep(500);
                        manualResetEvent.WaitOne();//用于判断是“暂停” 还是 “继续” 线程
                        this.Invoke(new Action(() =>
                        {
                            this.richTextBox1.Text += this.counter++ + ",";
                        }));
                    }
                    catch(Exception ex)
                    {
                        MessageBox.Show(ex.Message + "异常位置:" + counter++);
                    } 
                }
            });
            thread.Start();
        }
        //暂停
        private void button2_Click(object sender, EventArgs e)
        {
            if(thread.ThreadState == System.Threading.ThreadState.WaitSleepJoin)
            {
                manualResetEvent.Reset();//让线程受阻
            }
        }
        //继续
        private void button3_Click(object sender, EventArgs e)
        {
            if(thread.ThreadState == System.Threading.ThreadState.WaitSleepJoin)
            {
                manualResetEvent.Set();//允许等待的线程继续进行
            }
        }
        //中断
        private void button4_Click(object sender, EventArgs e)
        {
            thread.Interrupt();
        }
        //中止
        private void button5_Click(object sender, EventArgs e)
        {
            thread.Abort();
        }
        //主线程等待子线程的结束
        private void button6_Click(object sender, EventArgs e)
        {
            Thread thread = new Thread(() =>
            {
                Console.WriteLine("子线程在运行中...");
                Thread.Sleep(3000);
                Console.WriteLine("子线程结束");
            });

            thread.Start();
            thread.Join();//主线程会等待子线程完成后,再执行
            Console.WriteLine("主线程执行完毕");
        }
    }
}

是通过给API 传入委托类型的参数来实现的

using System;
using System.Threading;

namespace ConsoleApp1
{
    internal class Program
    {
        static void Main(string[] args)
        {
            //用函数名来给委托赋值
            Thread thread1 = new Thread(TStart);
            //用匿名函数给委托赋值
            Thread thread2 = new Thread(delegate ()
            {
                Console.WriteLine("线程启动... 2");
            });
            //用Lambda表达式给委托赋值
            Thread thread3 = new Thread(() =>
            {
                Console.WriteLine("线程启动... 3");
            });


            //启动
            thread1.Start();
            thread2.Start();
            thread3.Start();
            Console.ReadLine();
        }
        static void TStart()
        {
            Console.WriteLine("线程启动... 1");
        }
    }
}

一个简单的例子:

using System;
using System.Threading;

namespace ConsoleApp1
{
    internal class Program
    {
        static void Main(string[] args)
        {

            Thread thread = new Thread(() =>
            {
                Console.WriteLine("线程启动...");
            });
            thread.IsBackground = true;//将其设置为后台线程  
            thread.Start();//启动
            Console.WriteLine("这里是主线程的输出");
            Console.ReadLine();
        }
    }
}

线程的开销(空间、时间)
在这里插入图片描述

在子线程里完成对主线程控件的操作(Invoke / BeginInvoke / InvokeRequired)

Invoke 阻塞
BeginInvoke 非阻塞
InvokeRequired 检查当前显示是否为子线程

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        //阻塞的
        void ThreadTestFunction1()
        {
            Thread thread = new Thread(() =>
            {
                
                this.label1.Invoke(new Action<string>(data =>
                {
                    Thread.Sleep(3000);
                    this.label1.Text = data;
                }), "200");
                Console.WriteLine("111111111111");
            });
            thread.Start();
        }

        //非阻塞的
        void ThreadTestFunction2()
        {
            Thread thread = new Thread(() =>
            {
                
                this.label2.BeginInvoke(new Action<string>(data =>
                {
                    Thread.Sleep(3000);
                    this.label2.Text = data;
                }), "201");
                Console.WriteLine("22222222222222");
            });
            thread.Start();
        }

        //子线程和主线程都可以调用的方法
        void ThreadTestFunction3()
        {
            if (this.label3.InvokeRequired) //如果是子线程访问
            {
                //this.label3.Invoke(new Action<string>(data =>
                //{
                //    this.label3.Text = data;
                //}),"900");
                this.label3.Invoke(new Action<string>(data =>
                {
                    this.label3.Text = data;
                }), "900");
            }
            else                            //如果是父线程访问
            {
                this.label3.Text = "901";
            }
        }
        private void button1_Click(object sender, EventArgs e)
        {
            ThreadTestFunction1();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            ThreadTestFunction2();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            ThreadTestFunction3();
        }


    }
}

之前版本的线程池(ThreadPool.QueueUserWorkItem)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    internal class Program
    {
        static void Main(string[] args)
        {
            //TestThreadPoolFunction1();
            //TestThreadPoolFunction2();
            TestThreadPoolFunction3();
            Console.ReadLine();
        }
        static void TestThreadPoolFunction1()
        {
            ThreadPool.QueueUserWorkItem(x=>
            {
                Console.WriteLine("子线程:" + Thread.CurrentThread.ManagedThreadId);
            },"116");
            Console.WriteLine("主线程:" + Thread.CurrentThread.ManagedThreadId);
        }
        static void TestThreadPoolFunction2()
        {
            ThreadPool.QueueUserWorkItem(x =>
            {
                Console.WriteLine("子线程:" + Thread.CurrentThread.ManagedThreadId);
                Console.WriteLine("传入线程的参数为:" + x);
            }, "116");
            Console.WriteLine("主线程:" + Thread.CurrentThread.ManagedThreadId);
        }
        static void TestThreadPoolFunction3()
        {
            for(int i = 0; i < 10; ++i)
            {
                ThreadPool.QueueUserWorkItem(x =>
                {
                    Console.WriteLine(string.Format("子线程:{0},传入线程的参数为:{1}", Thread.CurrentThread.ManagedThreadId,x));
                    Thread.Sleep(50);
                }, i);
                Console.WriteLine("主线程:" + Thread.CurrentThread.ManagedThreadId);
            }
        }
    }
}

九、多线程(Task)

开启的三种方式

using System;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    internal class Program
    {
        static void Main(string[] args)
        {
            //方式一:先创建对象,再开启线程
            Task task1 = new Task(() =>
            {
                Console.WriteLine("线程ID:" + Thread.CurrentThread.ManagedThreadId);
            });
            task1.Start();

            //方式二、三:在创建的地方开启线程
            Task.Run(() =>
            {
                Console.WriteLine("线程ID:" + Thread.CurrentThread.ManagedThreadId);
            });

            Task.Factory.StartNew(() =>
            {
                Console.WriteLine("线程ID:" + Thread.CurrentThread.ManagedThreadId);
            });

            Console.ReadLine();
        }
    }
}

终止 / 重启(用信号源对线程进行控制)

在这里插入图片描述

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        //取消任务信号源
        private CancellationTokenSource cts = new CancellationTokenSource();

        //启动线程
        private void button1_Click(object sender, EventArgs e)
        {
            if (cts.IsCancellationRequested)//之前的信号源被取消了,则更换一个新的信号源
            {
                cts = new CancellationTokenSource();
            }
            Task.Run(() =>
            {
                int counter = 0;
                while (!cts.IsCancellationRequested)
                {
                    counter++;
                    Thread.Sleep(1000);

                    Console.WriteLine(counter);
                }
            }, cts.Token);  
        }

        //停止线程
        private void button2_Click(object sender, EventArgs e)
        {
            cts.Cancel();//调用这个方法,线程就可以停止执行了
        }
    }
}

暂停 / 继续 (用时间对象对线程进行控制)

在这里插入图片描述

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            
            Task.Run(() =>
            {
                int counter = 0;
                while (true)
                {
                    mResetEvent.WaitOne();//用来控制暂停和继续

                    counter++;
                    Thread.Sleep(1000);

                    Console.WriteLine(counter);
                }
            });  
        }
        
        //手动停止事件对象
        private ManualResetEvent mResetEvent = new ManualResetEvent(true);

        //启动线程
        private void button1_Click(object sender, EventArgs e)
        {
            mResetEvent.Set();//继续
        }

        //停止线程
        private void button2_Click(object sender, EventArgs e)
        {
            mResetEvent.Reset();//暂停
        }
    }
}

执行一段时间后停止

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        //用于控制线程
        private CancellationTokenSource cts = new CancellationTokenSource();

        public Form1()
        {
            InitializeComponent();
            
            Task task = new Task(() =>
            {
                int counter = 0;
                while (!cts.IsCancellationRequested)
                {
                    counter++;
                    Thread.Sleep(1000);

                    Console.WriteLine(counter);
                }
            }, cts.Token);

            //线程开启 3 秒后结束线程
            cts.CancelAfter(3000);

            //开启线程
            task.Start();
        }

    }
}

执行完后,执行回调函数

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        //用于控制线程
        private CancellationTokenSource cts = new CancellationTokenSource();

        public Form1()
        {
            InitializeComponent();

            Task task = new Task(() =>
            {
                Console.WriteLine("线程进行中 1");
                Thread.Sleep(1000);
                Console.WriteLine("线程进行中 2"); 
                Thread.Sleep(1000);
                Console.WriteLine("线程进行中 3"); 
                Thread.Sleep(1000);

                cts.Cancel();//执行这个(或者这个 CancelAfter),才会去执行,结束的回调(Register)
            }, cts.Token);


            cts.Token.Register(() =>
            {
                Console.WriteLine("线程结束了");
            });

            //开启线程
            task.Start();
        }

    }
}

执行多个或者多个的一个后执行回调线程(API:ContinueWith)

using System;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            Task task1 = new Task(() =>
            {
                Thread.Sleep(1000);
                Console.WriteLine("task1,线程号:"+Thread.CurrentThread.ManagedThreadId);
            });
            Task task2 = new Task(() =>
            {
                Thread.Sleep(2000);
                Console.WriteLine("task2,线程号:" + Thread.CurrentThread.ManagedThreadId);
            });
            Task task3 = new Task(() =>
            {
                Thread.Sleep(3000);
                Console.WriteLine("task3,线程号:" + Thread.CurrentThread.ManagedThreadId);
            });

            task1.Start();
            task2.Start();
            task3.Start();


            //或者:Task.WaitAny(task1, task2, task3).CiontinueWith(...)

            Task.WhenAll(task1, task2, task3).ContinueWith(t =>
            {
                Thread.Sleep(1000);
                Console.WriteLine("后面开启的线程:" + Thread.CurrentThread.ManagedThreadId);
            });


            Console.WriteLine("主线程,线程号:"+Thread.CurrentThread.ManagedThreadId);
        }
    }
}

主线程等待子线程的三种API:

using System;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            Task task1 = new Task(() =>
            {
                Thread.Sleep(1000);
                Console.WriteLine("task1,线程号:"+Thread.CurrentThread.ManagedThreadId);
            });
            Task task2 = new Task(() =>
            {
                Thread.Sleep(2000);
                Console.WriteLine("task2,线程号:" + Thread.CurrentThread.ManagedThreadId);
            });
            Task task3 = new Task(() =>
            {
                Thread.Sleep(3000);
                Console.WriteLine("task3,线程号:" + Thread.CurrentThread.ManagedThreadId);
            });

            task1.Start();
            task2.Start();
            task3.Start();

            //第一种阻塞方式
            //task1.Wait();
            //task2.Wait();
            //task3.Wait();

            //第二种阻塞方式
            //Task.WaitAll(task1, task2, task3);

            //第三种阻塞方式
            Task.WaitAny(task1, task2, task3);

            Console.WriteLine("主线程,线程号:"+Thread.CurrentThread.ManagedThreadId);
        }
    }
}

-----------------------------

跨线程访问(在子线程中,去操作主线程中的内容)

就是在开启线程的地方添加一个入参
TaskScheduler.FromCurrentSynchronizationContext()
在这里插入图片描述

using System;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        //卡顿
        private void button1_Click(object sender, EventArgs e)
        {
            Task task = new Task(() =>
            {
                Thread.Sleep(3000);//延时操作会卡顿UI
                this.label1.Text = "-新的内容";
            });
            task.Start(TaskScheduler.FromCurrentSynchronizationContext());
        }

        //不卡顿
        private void button2_Click(object sender, EventArgs e)
        {
            Task task = new Task(() =>
            {
                Thread.Sleep(3000);//延时操作会卡顿UI
            });

            task.ContinueWith(t =>
            {
                this.label1.Text = "新的内容";
            }, TaskScheduler.FromCurrentSynchronizationContext());
            task.Start();
        }
    }
}

-------------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    internal class Program
    {
        private static readonly Object mylock = new object();

        private static int counter = 0;
        static void Main(string[] args)
        {
            Test();
            Console.ReadLine();
        }

        static void Test()
        {
            for(int i = 0; i < 10;++i)
            {
                Task.Run(() =>
                {
                    for (int j = 0; j < 100; j++)
                    {
                        //lock (this)//静态类里用不了 this
                        lock (mylock)
                        {
                            Console.WriteLine($"id:{Thread.CurrentThread.ManagedThreadId}-couter:{counter++}");
                        }
                        
                    }
                });
            }
        }
    }
}

十、多线程 (async、await)

据说这个一个语法糖,目的是为了更方便的写异步

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Test();
            Console.WriteLine("这里是主线程的内容..." + ",线程ID:" + Thread.CurrentThread.ManagedThreadId);
            Console.ReadLine();          
        }

        async static void Test()
        {
            await Task.Run(() =>
            {
                Console.WriteLine("线程开始了"+",线程ID:"+Thread.CurrentThread.ManagedThreadId);
                Thread.Sleep(3000);
                Console.WriteLine("线程快要结束了" + ",线程ID:" + Thread.CurrentThread.ManagedThreadId);
            });

           Console.WriteLine("这里是异步回调里执行的内容..." + ",线程ID:" + Thread.CurrentThread.ManagedThreadId);
        }
    }
}

执行的顺序(打印):
在这里插入图片描述

十一、LINQ

模仿 SQL 语句来写内存中的查询

一个简单的例子

/*
 *  将一个 int数组中的奇数挑出来,后从小到大排列
 */

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApp1
{
    internal class Program
    {


        static void Main(string[] args)
        {
            Test1();
            Test2();
            Console.ReadLine();
        }

        static int[] nums = { 1, 6, 9, 3, 7, 38, 16, 68, 42, 99, 33 };


        //不使用 LINQ
        public static void Test1()
        {

            List<int> result = new List<int>();
            //找到奇数
            foreach(int item in nums)
            {
                if (item % 2 != 0)
                {
                    result.Add(item);
                }
            }
            result.Sort();//排序
            result.Reverse();//使之逆序

            //打印
            foreach (int item in result)
            {
                Console.Write(item + ",");
            }
            Console.WriteLine();
        }

        //使用 LINQ
        public static void Test2()
        {
            var result = from num in nums
                         where num % 2 != 0
                         orderby num descending
                         select num;

            //打印
            foreach(int item in result)
            {
                Console.Write(item+",");
            }
            Console.WriteLine();
        }
    }
}

原理:

用于拓展方法,和返回泛型接口,写链式编程
在这里插入图片描述

扩展方法 查询函数

select 处理(1、改变值, 2、从类中去除需要筛选的元素)
where 过滤
orderBy 升序排列
OrderByDescending 降序排列
GroupBy 分组
Distinct 去除重复元素

在这里插入图片描述

/**
 *  Linq 查询语句
 *
 */

/**
 *  Linq 查询语句
 *
 */

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApp1
{
    internal class Program
    {


        static void Main(string[] args)
        {
            Test1();
            Test1_1();
            Test2();
            Test3();
            Test4();
            Test5();
            Test6();

            Console.ReadLine();
        }

        static int[] nums = { 1, 1, 1, 6, 9, 3, 7, 38, 16, 68, 42, 99, 33 };

        public class A
        {
            public int x;
            public int y;
            public string z;
        }

        //扩展方法 Select
        public static void Test1()
        {
            var result = nums.Select(x => x * x);

            //打印
            foreach (int item in result)
            {
                Console.Write(item + ",");
            }
            Console.WriteLine();
        }

        public static void Test1_1()
        {
            A[] Class_A_Array = { new A() { x = 1 }, new A() { x = 2 }, new A() { x = 3 } };
            var result = Class_A_Array.Select(classA => classA.x);

            //打印
            foreach (int item in result)
            {
                Console.Write(item + ",");
            }
            Console.WriteLine();
        }

        //扩展方法 Where
        public static void Test2()
        {
            var result = nums.Where(x => x < 10);

            //打印
            foreach (int item in result)
            {
                Console.Write(item + ",");
            }
            Console.WriteLine();
        }

        //扩展方法 OrderBy
        public static void Test3()
        {
            var result = nums.OrderBy((x) => x);

            //打印
            foreach (int item in result)
            {
                Console.Write(item + ",");
            }
            Console.WriteLine();
        }

        //扩展方法 OrderByDescending
        public static void Test4()
        {
            var result = nums.OrderByDescending(x => x);

            //打印
            foreach (int item in result)
            {
                Console.Write(item + ",");
            }
            Console.WriteLine();
        }

        //扩展方法 GroupBy
        public static void Test5()
        {
            var result = nums.GroupBy(x => x % 10);//个位数相同的分为一组

            //打印
            Console.WriteLine("--------------------------");
            foreach (var items in result)
            {
                foreach (int item in items)
                {
                    Console.Write(item + ",");
                }
                Console.WriteLine();
            }
            Console.WriteLine("--------------------------");
        }

        //扩展方法 OrderByDescending
        public static void Test6()
        {
            var result = nums.Distinct();

            //打印
            foreach (int item in result)
            {
                Console.Write(item + ",");
            }
            Console.WriteLine();
        }

    }
}

<查询语句> 混合 <扩展方法> 的写法

查询语句一种,更方便调用 扩展方法 的写法
但是有些 查询语句没有对应的 查询语句的写法,所以有的时候需要混合起来写

Count 计数

/**
 *  聚合函数 count
 */

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApp1
{
    internal class Program
    {
        public class A
        {
            public int x;
            public int y;
            public string z;
        }
        static List<A> list;
        static void Main(string[] args)
        {
            
            //初始化需要 查询的内容
            A a1 = new A() { x = 1, y = 1, z = "a" };
            A a2 = new A() { x = 2, y = 1, z = "b" };
            A a3 = new A() { x = 3, y = 1, z = "c" };
            A a4 = new A() { x = 4, y = 1, z = "d" };
            A a5 = new A() { x = 5, y = 1, z = "e" };
            A a6 = new A() { x = 6, y = 1, z = "f" };
            A a7 = new A() { x = 7, y = 1, z = "g" };
            list = new List<A>() { a1, a2, a3, a4, a5, a6, a7 };

            Test1();

            Console.ReadLine();
        }

        //扩展方法 Count
        public static void Test1()
        {
            var count = (from x in list
                         where x.x > 3
                         select x).Count();

            //打印
            Console.WriteLine($"count:{count}");
        }
    }
}

聚合函数

Count 计数
Max 找到最大值
Min 找到最小值
Average 计算平均值
Sum 统计总和

/**
 *  聚合函数
 *
 */

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApp1
{
    internal class Program
    {
        public class A
        {
            public int x;
            public int y;
            public string z;
        }
        static List<A> list;
        static void Main(string[] args)
        {
            
            //初始化需要 查询的内容
            A a1 = new A() { x = 1, y = 1, z = "a" };
            A a2 = new A() { x = 2, y = 1, z = "b" };
            A a3 = new A() { x = 3, y = 1, z = "c" };
            A a4 = new A() { x = 4, y = 1, z = "d" };
            A a5 = new A() { x = 5, y = 1, z = "e" };
            A a6 = new A() { x = 6, y = 1, z = "f" };
            A a7 = new A() { x = 7, y = 1, z = "g" };
            list = new List<A>() { a1, a2, a3, a4, a5, a6, a7 };

            Test1();
            Test2();

            Console.ReadLine();
        }

        //扩展方法 Count
        public static void Test1()
        {
            var count = (from x in list
                         where x.x > 3
                         select x).Count();

            //打印
            Console.WriteLine($"count:{count}");
        }

        //扩展方法 Max Min Average Sum
        public static void Test2()
        {
            var max = (from x in list
                         select x.x).Max();

            var min = (from x in list
                       select x.x).Min();

            var avg = (from x in list
                       select x.x).Average();

            var sum = (from x in list
                       select x.x).Sum();

            //打印
            Console.WriteLine($"max:{max}");
            Console.WriteLine($"min:{min}");
            Console.WriteLine($"avg:{avg}");
            Console.WriteLine($"sum:{sum}");
        }
    }
}

多项 综合排序 的写法

查询语句
orderby
扩展方法
.OrderBy(s=>s.x)
.ThenBy(s=>s.y)
//.ThenBy(s=>s.z);
.ThenByDescending(s=>s.z);

ThenBy:用于在当前排序的基础上进行升序排列。
ThenByDescending:用于在当前排序的基础上进行降序排列。

/**
 *  混合排序
 *
 */

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApp1
{
    internal class Program
    {
        public class A
        {
            public int x;
            public int y;
            public string z;
        }
        static List<A> list;
        static void Main(string[] args)
        {

            //初始化需要 查询的内容
            A a11 = new A() { x = 1, y = 2, z = "a" };
            A a12 = new A() { x = 1, y = 1, z = "a" };
            A a13 = new A() { x = 1, y = 3, z = "c" };
            A a14 = new A() { x = 1, y = 3, z = "a" };
            A a15 = new A() { x = 1, y = 3, z = "b" };
            A a2 = new A() { x = 6, y = 3, z = "b" };
            A a3 = new A() { x = 7, y = 2, z = "c" };
            A a4 = new A() { x = 4, y = 1, z = "d" };
            A a5 = new A() { x = 5, y = 5, z = "e" };
            A a6 = new A() { x = 2, y = 6, z = "f" };
            A a7 = new A() { x = 3, y = 7, z = "g" };
            list = new List<A>() { a11, a12, a13, a14, a15, a2, a3, a4, a5, a6, a7 };

            Test1();
            Test2();

            Console.ReadLine();
        }

        // 查语句的方式
        public static void Test1()
        {
            var newList = from x in list
                          orderby x.x, x.y
                          select x;

            //打印
            Console.WriteLine("-----------------------");
            foreach (A a in newList)
            {
                Console.WriteLine($"{a.x}-{a.y}-{a.z}");
            }
        }

        // 扩展方法的方式
        public static void Test2()
        {
            var newList = list
                .Select(s=>s)
                .OrderBy(s=>s.x)
                .ThenBy(s=>s.y)
                //.ThenBy(s=>s.z);
                .ThenByDescending(s=>s.z);

            //打印
            Console.WriteLine("-----------------------");
            foreach (A a in newList)
            {
                Console.WriteLine($"{a.x}-{a.y}-{a.z}");
            }
        }
    }
}

创建集合

Range 按一个范围生成
Repeat 生成重复的

/**
 *  创建序列
 *
 */

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApp1
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Test1();
            Console.ReadLine();
        }

        // 
        public static void Test1()
        {
            var nums1 = Enumerable.Range(0, 10);
            var nums2 = Enumerable.Repeat("asd", 10);

            //打印
            Console.WriteLine("-----------------------");
            foreach (var a in nums1)
            {
                Console.WriteLine(a);
            }

            Console.WriteLine("-----------------------");
            foreach (var a in nums2)
            {
                Console.WriteLine(a);
            }
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值