代码之家  ›  专栏  ›  技术社区  ›  Joel Coehoorn

在一般集合中,“dynamic”类型能否安全地变化?

  •  10
  • Joel Coehoorn  · 技术社区  · 16 年前

    基于我对 this question ,我想检查一下我对即将到来的 dynamic C 4的类型。

    在本例中,我们有一个集合,它表示从未知数据库表中提取的记录中的字段。旧代码(pre-.net 4)要求这样的集合保留类型的项 Object . 撇开这些收藏的优点不谈,我想知道当你改变的时候会发生什么 对象 动态 .

    一方面,我希望由于动态类型的内容都是在运行时完成的,所以只要程序员不在集合中某个特定项的预期类型上做任何拼写错误或错误,一切都应该很好。

    另一方面,我对前一句中的“all”这个词感到疑惑。运行时是否会缓存第一次访问动态属性时的结果,从而导致使用不同类型的后续调用失败?

    4 回复  |  直到 16 年前
        1
  •  3
  •   Eric Lippert    16 年前

    下面是山姆博客中有关缓存政策的内容。

    http://blogs.msdn.com/samng/archive/2008/10/29/dynamic-in-c.aspx

    DLR检查缓存以查看 给定的操作已绑定 与当前参数集相反。 所以在我们的示例中,我们将执行一个类型 基于1、2和运行时匹配 D类型。如果缓存命中, 然后返回缓存的结果。如果 我们没有缓存命中,然后 DLR检查接收器是否 田园牧歌。这些家伙是 基本上是知道如何 注意自己的约束,比如 作为COM IDispatch对象,真实动态 诸如ruby或python的对象, 或实现的某个.NET对象 IDynamicObject接口。如果是 任何这些,然后DLR取消 并要求它绑定 行动。

    请注意,调用 要绑定的IDO是一个表达式树, 表示绑定的结果。 如果不是IDO,那么DLR 调用语言活页夹(在 case,要绑定的c运行时绑定器) 手术。C运行时绑定器 将绑定操作,然后返回 表示 绑定的结果。一次步骤2或3 已经发生了,结果 表达式树合并到 缓存机制,以便 后续调用可以针对 缓存而不是反弹。

    但是,Sam没有提到的是什么是缓存未命中策略。有两个主要的缓存未命中策略:(1)在参数类型更改时触发缓存未命中;(2)在参数标识更改时触发缓存未命中。

    显然,前者的性能要高得多;仅仅根据类型来计算何时可以进行缓存是很困难的。对所有这些逻辑如何工作的详细解释将花费相当长的时间;希望有一天我或克里斯或萨姆会在上面写一篇博文。

        2
  •  1
  •   Ana Betts    16 年前

    您可以将dynamic视为使用reflection和methodinfo.invoke()编写所有方法调用的语法甜品-在这种情况下,它的工作方式并不完全相同,但您可以将其视为工作方式,同时考虑到所有与之相关的“通过dynamic=>谋杀性能调用1000个方法/秒”考虑因素。

        3
  •  1
  •   Marc Gravell    16 年前

    至于 词典 / 列表 关心的是,它能看到 object . dynamic 主要在旁观者的眼中——即 打电话 代码;在引擎盖下面是“物体加一点糖”。所以你不应该在这里看到任何问题。

    证明:

        static void Main()
        {
            Console.WriteLine(IsObject<int>()); // false
            Console.WriteLine(IsObject<object>()); // true
            Console.WriteLine(IsObject<dynamic>()); // true
            Console.WriteLine(IsObject<string>()); // false
        }
        static bool IsObject<T>()
        {
            return typeof(T) == typeof(object);
        }
    
        4
  •  1
  •   Joel Coehoorn    16 年前

    好吧,我启动了Visual Studio 2010 Beta 2,这个测试程序运行正常,而不是等待答案:

    class Foo
    {
        public string foo = "Foo!";
    }
    class Bar
    {
        public int bar = 42;
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            var test = new List<dynamic>();
            test.Add(new Foo());
            test.Add(new Bar());
    
            Console.WriteLine(test[0].foo.Substring(0,3));
            Console.WriteLine(test[1].bar.ToString("000"));
    
            Console.ReadKey(true);
        }
    }
    

    我想确保不仅检查了具有不同名称的属性,而且还检查了具有不同类型的属性,以及在每种类型中使用了彼此不兼容的功能。这个 似乎 建议 如果 任何东西都是缓存的,运行时足够智能,可以知道何时使用缓存,何时不使用。我仍然想知道,如果有人知道一个边缘案件,这可能不成立,或更权威的评论,为什么会这样。

    推荐文章