【问题标题】:Extension methods & dynamic vars扩展方法和动态变量
【发布时间】:2019-12-16 10:40:29
【问题描述】:

动态变量是否有理由不支持扩展方法?有办法规避吗?

这是一个例子:

我没有忘记持有我正在使用的扩展方法的类的 using 指令:

using System.Linq;

这段代码没有问题:

IEnumerable<string> ie = new HashSet<string>() { "test" };
Console.WriteLine(ie.ToList()[0]);

这个抛出异常:

IEnumerable<string> ie = new HashSet<string>() { "test" };
Console.WriteLine(((dynamic)ie).ToList()[0]);

''System.Collections.Generic.HashSet' 不包含'ToList''的定义

【问题讨论】:

    标签: c# .net dynamic extension-methods


    【解决方案1】:

    来自 Linq 的 ToList 需要 编译时间-IEnumerable。通过使用dynamic,您完全隐藏了编译时类型,并使编译器无法推断出正确的方法。所以你依赖运行时绑定。

    现在扩展方法只是static 方法的语法糖:

    static class Enumerable
    {
        public static List<T> ToList(IEnumerable<T> e) { ...}
    }
    

    你会这样称呼它:

    Enumerable.ToList(myHashSet);
    

    这也是编译器所做的。它将所有对hashSet.ToList() 的调用转换为Enumerable.ToList(hashSet)

    此方法与您的实际类(哈希集)无关,因为扩展方法不会修改现有类。他们只是定义了看起来就像被添加到类中的方法。或者换句话说:在运行时 - 这是在评估 dynamic 时 - 没有这样的方法 HashSet.ToList,但是 Enumerable.ToList

    【讨论】:

    • 这意味着,如果我必须处理动态,我不能使用扩展方法(除了将动态转换为 IEnumerable)?
    • @Sébastien 好吧,老实说,我会尽量避免使用dynamic。事实上,我真的很少需要那个。
    • 我也尽可能多地这样做,但我正在开发一个模板解析器,它将 Word 文档中的变量与应用程序中这些变量的值进行转换。即:[Path.To.My.Array[0].Property] = 可枚举“Path.To.My.Array”的第一个对象中“Property”的值。其中 Property 可以是 int、string...,Array 可以是数组、List 或任何 IEnumerable 和 {Path, To, My} 是对象。所以,为了尽可能地抽象而不处理所有可能性,我必须使用动态变量。
    • @Sébastien 不一定。投射到ICollection 甚至IList 怎么样?它们还提供基于索引的访问。
    • 是的,这就是我要做的,这只是为了解释为什么我必须处理动态变量(至少要获取相应变量的值),因为我不知道提前我要获取的 var 的类型是什么。
    猜你喜欢
    • 2011-07-15
    • 1970-01-01
    • 1970-01-01
    • 2013-01-18
    • 2018-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多