美文网首页程序员
记一个动态类型问题

记一个动态类型问题

作者: 转交遇见陈绮贞 | 来源:发表于2016-04-23 01:38 被阅读49次

    问题情景#

    订单页面需要展示不同订单的游客信息,订单信息有一个公共数据实体,而游客有不同的两个不同的数据实体,于是就有了类似下面的代码

        public class Order
        {
            public string SerialId = string.Empty;
            public dynamic Tours = null;
        }
        var order = new Order();
        order.Tours = new List<string>();
        order.Tours.Any();
    

    赋值后在前台将Tours as 成我们想要的游客数据实体列表,然后在判断是否存在数据时 order.Tours.Any()报错:“System.Collections.Generic.List<string>”未包含“Any”的定义

    问题分析#

    首先我们得到的确实是一个List类型,那么问题就出现在.Any()这个LINQ语句中,原因是“动态对象不支持扩展方法。lambda也不能用作动态方法调用的参数,因此LINQ不能用于动态对象。大多数LINQ调用都是扩展方法。”-C#高级编程
    这是why,那么why why?

        public class Program
        {
            static void Main(string[] args)
            {
                List<string> list = new List<string>();
                //dynamic list = new List<string>();
                list.Any();
            }
        }
    
    Paste_Image.png Paste_Image.png
    看上面的代码和截图,代码编译成IL后执行过程就已经明确下来,执行需要信息完备了。但是dynamic类型编译成的IL却并没有明确这些执行信息,而是在执行IL时去查找操作的类型,生成表达式树来绑定需要的操作。具体实现本人也还在研究中。

    重要的事情来了,dynamic类型生成的IL是动态去查找类型绑定方法,然而扩展方法并不是定义在目标类型中,而只是外部的一个扩展。这时候我们自然就无法找到需要调用的方法,也就会抛出出现开头的报错信息。

    解决方案#

    1. 如果目标类型确定的话,将dynamic类型强制转换成需要的类型赋值给一个中间变量,然后操作中间变量。
    2. 试着使用List<dynamic>来接收数据

    扩展延伸#

    1. 从上面的示例我们可以知道dynamic类型生成的IL远比一般代码要多得多,所以对性能的影响肯定是有的,建议非特殊情况下能不用dynamic类型就不用。就比如本人上面的代码。
    2. 对于IL等一些比较底层的东西,也许日常工作中不需要了解,但是能了解一些绝对是有帮助的。

    相关文章

      网友评论

        本文标题:记一个动态类型问题

        本文链接:https://www.haomeiwen.com/subject/fxbxrttx.html