• 匿名类型与元组(ValueTuple)


    匿名类型与元组(ValueTuple)

    匿名类型

    简介:匿名类型提供了一种方便的方法,可用来将一组相关的属性封装到单个对象中。匿名对象由编译器在编译时动态生成,它是只读的,且只在当前作用域中可见。它可以方便地在代码中传递和
    我的:不用写class直接new对象,组合数据,传递数据
    好处:避免编写不必要的类,提高编码效率,逻辑更清晰
    缺点:超出当前作用域,需使用dynamic或反射等方式来获取数据项
    应用:匿名对象通常用在LINQ的select字句及多返回值场景
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace demo匿名类型
    {
        public class Student
        {
            public int Id { get; set; }//学生编号
            public string Name { get; set; }//学生姓名
            public int Age { get; set; }//学生年龄
            public string Gender { get; set; }//学生性别
            public int ClassId { get; set; }//所在班级编号
        }
        public class Class
        {
            public int Id { get; set; }//班级编号
            public string ClassName { get; set; }//班级名称
            public string Teacher { get; set; }//班级教师
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    using System.Reflection;
    namespace demo匿名类型
    {
        internal class Program
        {
    
            static void Main(string[] args)
            {
                /********创建使用匿名类型对象********/
                var person = new { Name = "张三", Sex = "男", Age = 11 };
                Console.WriteLine($"Name:{person.Name},Sex:{person.Sex},Age:{person.Age}");
    
    
                /*动态类型处理匿名对象类型。缺点:属性名写错了,也不会报错,运行时出错。*/
                dynamic GetStudentInfo()
                {
                    return new { Name = "李四", Sex = "男", Age = 18 };
                }
                dynamic student = GetStudentInfo();
                Console.WriteLine($"Name:{student.Name},Sex:{student.Sex},Age:{student.Age}");
    
    
                /*****指定类型接受匿名对象类型(此技巧只在同一程序集中的代码才有效)*****/
                dynamic GetStudentInfo1()
                {
                    return new { Name = "", Sex = "", Age = 0 };
                }
                dynamic student1 = GetStudentInfo1();
                Console.WriteLine($"Name:{student.Name},Sex:{student.Sex},Age:{student.Age}");
    
    
                /*****通过反射获取匿名类型数据项(测试匿名类型作参数)*****/
                void Test(object obj)
                {
                    Type t = obj.GetType();
                    PropertyInfo? pName = t.GetProperty("Name");
                    PropertyInfo? pSex = t.GetProperty("Sex");
                    PropertyInfo? pAge = t.GetProperty("Age");
                    Console.WriteLine($"匿名类型:{t.Name}");
                    Console.WriteLine($"Name:{pName?.GetValue(obj)},Sex:{pSex?.GetValue(obj)},Age:{pAge?.GetValue(obj)}");
                }
                Test(new { Name = "王五", Sex = "男", Age = 20 });
    
                /******linq支持对匿名对象集合的查询处理******/
                var people = new[]
                {
                    new {Name = "李麻子" ,Sex = "男" , Age = 21 },
                    new {Name = "八戒" ,Sex = "男" , Age = 40 },
                    new {Name = "悟空" ,Sex = "男" , Age = 500 },
                    new {Name = "唐僧" ,Sex = "男" , Age = 25 }
                };
    
                //班级信息列表
                var classList = new List
                {
                    new Class{Id = 1 ,ClassName = "一年级一班" , Teacher = "张老师" },
                    new Class{Id = 2 ,ClassName = "一年级二班" , Teacher = "王老师" },
                    new Class{Id = 3 ,ClassName = "二年级一班" , Teacher = "赵老师" },
                    new Class{Id = 4 ,ClassName = "二年级二班" , Teacher = "李老师" }
                };
    
                //学生信息列表
                var studentList = new List
                {
                    new Student{Id = 1 ,Name = "张三" , Age = 8 ,Gender = "男",ClassId = 1},
                    new Student{Id = 2 ,Name = "李四" , Age = 9 ,Gender = "女",ClassId = 2},
                    new Student{Id = 3 ,Name = "王五" , Age = 8 ,Gender = "男",ClassId = 1},
                    new Student{Id = 4 ,Name = "赵六" , Age = 9 ,Gender = "女",ClassId = 2},
                    new Student{Id = 5 ,Name = "钱七" , Age = 7 ,Gender = "男",ClassId = 3},
                    new Student{Id = 6 ,Name = "孙八" , Age = 7 ,Gender = "女",ClassId = 3}
                };
    
                var query = from p in people
                            where p.Age > 30
                            select p;
    
                foreach (var Person in query)
                {
                    Console.WriteLine($"Name:{Person.Name},Sex:{Person.Sex},Age:{Person.Age}");
                }
    
                //使用LINQ进行联合查询,查询学生信息以及对应的班级信息
                var result = from s in studentList
                             join c in classList
                             on s.Id 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.班级教师}");
                }
    
                //使用 LINQ 进行联合查询,查询学生信息
                var result2 = from s in studentList
                             select new
                             {
                                 s.Id, //注:此处可简写,没写属性名,自动以赋值属性为名称
                                 s.Name
                             };
    
                //输出查询结果
                foreach (var item in result2)
                {
                    Console.WriteLine($"学生ID:{item.Id},学生姓名:{item.Name}");
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117

    元组ValueTuple使用技巧(一行代码交换两个变量的值)

                //数据互换(使用元组)
                string str1 = "长江";
                string str2 = "黄河";
                Console.WriteLine($"str1 = {str1}, str2 = {str2}");
                (str1,str2) = (str2,str1);
                Console.WriteLine($"str1 = {str1}, str2 = {str2}");
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    匿名类型与元组ValueTuple对比

    • 元组是一种泛型结构体,系统预定义好的;
    • 匿名类型不写class、new对象,元组也是一样;
    • 匿名类型 new{…},格式简介,元组更简洁(元素类型1,元素类型2,…)变量名;
                //使用元组(ValueTuple),将多个数据元素构成一个轻型数据结构
                (string, int) x = new ValueTuple("鲁班七号",12);
                (string, int) y = ValueTuple.Create("鲁班七号",12);
                //更简洁的语法
                (string, int) z = ("鲁班七号",12);
                Console.WriteLine($"姓名:{z.Item1},年龄:{z.Item2}");
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 匿名类型 属性名 = 属性值,元组ValueTuple 字段名:字段值
                //使用命名字段1
                var a = (name : "百里守约", age : 22);
                Console.WriteLine($"姓名:{a.name},\t年龄:{a.age}");
                //使用命名字段2
                (string name, int age) b = ("妲己",28);
                Console.WriteLine($"姓名:{b.name},\t年龄:{b.age}");
    
                //元组的解构
                (string name, int age) = ("廉颇",40);
                var (name1, age1) = ("廉颇",40);
                Console.WriteLine($"姓名:{name},\t年龄:{age}");
                Console.WriteLine($"姓名:{name1},\t年龄:{age1}");
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 元组ValueTuple参数,返回值方便
                //弃元,放弃不需要的元素
                var tuple = (1,'a' ,3.14);
                var (_,letter,_) = tuple;
                Console.WriteLine(letter);
    
                //元组作为参数
                void ProcessTuple((string name,int Age)person)
                {
                    Console.WriteLine($"Name:{person.name},Age:{person.Age}");
                }
                ProcessTuple(("东皇太一",80));
    
                //元组作为返回类型
                (int Sum, int Product)GetSumAndProduct(int a,int b)
                {
                    return (a + b , a * b);
                }
                var result3 = GetSumAndProduct(3,4);
                Console.WriteLine($"和:{result3.Sum},乘积:{result3.Product}");
    
                //使用元组作为返回值
                (string, int) GetPerson()
                {
                    return ("烬天玉藻前",30);
                }
                //调用方法并解构返回值
                (string name2, int age2) = GetPerson();
                Console.WriteLine($"Name:{name2},乘积:{age2}");
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 匿名函数在LINQ中使用方便,元组ValueTuple也在LINQ中使用方便
                //使用LINQ进行联合查询,查询学生信息以及对应的班级信息
                var result5 = from s in studentList
                             join c in classList
                             on s.Id equals c.Id
                             select
                             (
                                 学生姓名 : s.Name,
                                 年龄 : s.Age,
                                 性别 : s.Gender,
                                 班级名称 : c.ClassName,
                                 班级教师 : c.Teacher
                             );
    
                foreach (var item in result5)
                {
                    Console.WriteLine($"学生姓名:{item.学生姓名},年龄:{item.年龄}," +
                        $"性别:{item.性别},班级名称:{item.班级名称},班级教师:{item.班级教师}");
                }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 元组字段值可修改
                //元组可以修改
                var f = (name : "关羽", age : 38);
                f.name = "东皇太一";
                Console.WriteLine($"姓名:{f.name},\t年龄:{f.age}");
    
    • 1
    • 2
    • 3
    • 4
    • 元组类型支持相等运算符 == 和 != ,它比较的是各个元素
                //元组类型支持相等运算符 == 和 != ,它比较的是各个元素
                var data = (2,2.3);
                if ((2, 2.31) == data)
                {
                    Console.WriteLine("数据相等");
                }
                else
                {
                    Console.WriteLine("数据不相等");
                }
    
                //元组中可以使用任意数量的元素。
                var t = (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,"比尔盖茨");
                //系统已经帮我们重写了ToString方法,方便输出所有元素
                Console.WriteLine(t.ToString());
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    思维导图

    在这里插入图片描述

  • 相关阅读:
    如何在 Net6.0 中对 WebAPI 进行 JWT 认证和授权
    项目测试一半,需求要变更,测试人员怎么办?
    tarjan 缩点笔记
    修复mongodb未授权访问漏洞(漏洞编号:009711D8)
    【系统架构设计师】七、信息安全技术基础知识(信息安全的概念|信息安全系统的组成框架|信息加解密技术)
    C# BackgroundWorker原理图
    Pinpoint--基础--02--架构设计
    sonic-ios-bridge(sib)性能监控
    刷题记录:牛客NC16655[NOIP2005]过河
    OpenSSL/SSL.py报错:with _from_buffer(buf) as data:
  • 原文地址:https://blog.csdn.net/qq_40418109/article/details/134287342