C#中动态类型dynamic用法浅析

  动态类型dynamic是微软在.net framework 4.0开始引入的,其目的是在程序编译过程中忽略对类型的检查,等到运行时刻再明确定义的对象的类型。
  使用dynamic类型可以简化代码。如下面代码所示,有学生类型Student,包括多种属性定义。

	public class Student
    {
        public string Name;//姓名
        public int Age;//年龄
        public string Sex;//性别
        public string Address;//住址
        public string Grade;//年级
        public string PhoneNumber;//电话号码
    }

  现在需要做的是根据用户的输入条件在一组学生数据中进行数据过滤。如果用户输入的条件为空,则返回所有数据,如果不为空,则返回满足条件的学生信息。不用返回每个学生的所有信息,只要有姓名、性别和住址即可。
  最初的解决方式如下所示,根据条件是否为空,分别对学生信息集合进行处理,并返回及显示匿名对象集合。但是这段代码的问题是if和else中存在有重复代码,即显示检索结果那段是重复的。

	string gradeFilter = Console.ReadLine();
     if (string.IsNullOrEmpty(gradeFilter))
     {
         var result = from g in m_students
                      select new { Name = g.Name, Sex = g.Sex, Address = g.Address };

         foreach (var item in result)
         {
             Console.WriteLine(string.Format("{0}-{1}-{2}", item.Name, item.Sex, item.Address));
         }
     }
     else
     {
         var result = from g in m_students
                      where g.Grade==gradeFilter
                      select new { Name = g.Name, Sex = g.Sex, Address = g.Address };

         foreach (var item in result)
         {
             Console.WriteLine(string.Format("{0}-{1}-{2}", item.Name, item.Sex, item.Address));
         }
     }

     Console.ReadKey();

  由于没有办法将var result的定义提前到if语句之前(VS:隐式类型化的变量必须已初始化),也没法将null值赋予result(VS:无法将<null>赋予隐式类型化的变量)。首先想到的解决办法是再定义一个学生信息类,只包括姓名、性别和住址三个属性,然后替换linq语句中的匿名对象。
  这样虽然能够解决问题,但是却增加了代码量。这是就可以使用dynamic动态类型。
  关于dynamic动态类型的详细介绍可以查看参考文献1-4。简而言之,使用dynamic动态类型定义的对象:“变量的使用和对其成员的引用绕过编译时类型检查。 改为在运行时解析这些操作”。也就是说VS在编译时不会去检查dynamic动态类型定义的对象以及对对象属性的操作,而是在程序运行时再去明确对象的具体类型。

  于是将上述示例代码修改为以下方式,将result定义为dynamic动态类型,同时将显示过滤结果的代码放到最后,删除重复代码。程序的运行效果与上面的示例代码效果相同。

	dynamic result;

    string gradeFilter = Console.ReadLine();
    if (string.IsNullOrEmpty(gradeFilter))
    {
        result = from g in m_students
                     select new { Name = g.Name, Sex = g.Sex, Address = g.Address };
        
    }
    else
    {
        result = from g in m_students
                     where g.Grade==gradeFilter
                     select new { Name = g.Name, Sex = g.Sex, Address = g.Address };
    }

    foreach (var item in result)
    {
        Console.WriteLine(string.Format("{0}-{1}-{2}", item.Name, item.Sex, item.Address));
    }

    Console.ReadKey();

  上述内容是初步学习参考文献中关于dynamic动态类型的一些认识,理解的可能不全或有所偏颇,欢迎批评指正。

参考文献
[1]https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/builtin-types/reference-types#the-dynamic-type
[2]https://docs.microsoft.com/zh-cn/dotnet/api/system.dynamic.dynamicobject?view=net-5.0
[3]https://docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/types/walkthrough-creating-and-using-dynamic-objects
[4]https://www.dazhuanlan.com/2019/09/13/69ab7f586028/

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值