【问题标题】:Possible to overwrite items in IEnumerable<T> using Reflection?可以使用反射覆盖 IEnumerable<T> 中的项目吗?
【发布时间】:2011-04-08 13:41:32
【问题描述】:

无视任何理智的理由这样做,只是出于好奇

是否可以采用任何给定的 IEnumerable(T) 并覆盖包含的项目?例如,给定一个 IEnumerable(String) 是否可以完全替换 IEnumerable 中的所有字符串?

【问题讨论】:

  • 大家 - 感谢您的精彩回答!我现在有全图。希望我能接受多个答案....

标签: .net reflection .net-4.0 .net-2.0


【解决方案1】:

正如其他人所说,如果 IEnumerable 是具体的东西,例如 List 或 Collection、Set 等,那么您无需反射即可执行此操作 - 只需将其转换为该类型并搞砸它。

如果 IEnumerable 是使用迭代器生成的,例如:

public IEnumerable<int> EvenNumbers
{
    get
    {
        int i = 2;

        while (true)
        {
            yield return i;
            i += 2;
        }
    }
}

你怎么能进入这个并替换一些价值?没有要替换的值 - 下一个值来自循环的下一次评估。内存中没有对这个 Enumerable 的完整评估,你必须不断地询问下一个值,直到你得到你想要的。

所以不,您不能保证您可以挖掘并修改所有 IEnumerables 的基础值,因为有时没有基础值。

【讨论】:

    【解决方案2】:

    理论上我想是的;不过……

    • 可靠地查看IEnumerable 中的对象的唯一方法是通过枚举(否则您必须对特定类进行硬编码)
    • 按照惯例,更改IEnumerable 中的任何值都会使枚举无效。这不一定是强制执行的;但是,它肯定是由框架类强制执行的(应该对用户创建的IEnumberables 也强制执行。

    来自MSDN's page on IEnumerator

    只要集合保持不变,枚举数就保持有效。如果对集合进行了更改,例如添加、修改或删除元素,则枚举器将不可恢复地失效,并且下一次调用 MoveNext 或 Reset 将引发 InvalidOperationException。如果集合在 MoveNext 和 Current 之间进行了修改,则 Current 返回它设置为的元素,即使枚举器已经失效。

    因此...不太可能!

    【讨论】:

      【解决方案3】:

      反射使您可以访问对象上定义的方法,这些方法未以对象当前转换为的类型公开。

      IEnumerable&lt;T&gt; 不公开任何替换项目的方法。但请记住,IEnumerable&lt;T&gt; 只是一个接口,而您的对象将是一个具体的实现。

      所以如果底层对象是List&lt;T&gt;,你可以轻松地说无需反射

      IEnumerable<MyType> list = ... // getting the enumerable
      List<MyType> realList = (List<MyType>) list;
      realList[0] = somethingElse;
      

      所以要看底层类型,IEnumerable&lt;T&gt;只是一个接口。

      【讨论】:

      • 我会首先检查 IList&lt;T&gt; 是否是支持索引的其他类型的容器。
      【解决方案4】:

      我怀疑您是否可以使用“任何 IEnumerable”,因为有些可能是惰性求值的,并且在您要求之前没有 T 可以覆盖。

      但您可能会检查实现 IEnumerable 的集合的特殊情况 - 列表、集合等 - 并以这种方式进行更改。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-22
        • 1970-01-01
        • 2011-06-01
        • 2011-04-02
        • 1970-01-01
        • 2021-08-23
        相关资源
        最近更新 更多