可以使用Reflection?</t>覆盖IEnumerable <t>中的项目

时间:2011-04-08 13:41:32

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

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

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

4 个答案:

答案 0 :(得分:5)

正如其他人所说的那样,如果IEnumerable是具体的东西,比如List或Collection,Set等,那么你可以不用反射就做到这一点 - 只需将它转换为那种类型并弄乱它。

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

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

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

你怎么能达到这个并取代一些价值?没有要替换的值 - 下一个值来自循环的下一个评估。在任何地方都没有对这个Enumerable进行全面评估,你必须继续询问下一个值,直到得到你想要的东西。

所以不,你不能保证对于所有IEnumerables你可以挖掘并修改基础值,因为有时候没有潜在的价值。

答案 1 :(得分:1)

理论上我会想象是的;然而...

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

来自MSDN's page on IEnumerator

  

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

因此......不太可能!

答案 2 :(得分:1)

Reflection允许您访问在对象上定义的方法,这些方法未在对象当前转换为的类型中公开。

IEnumerable<T> 不会公开任何替换项目的方法。但请记住,IEnumerable<T>只是一个界面,而您的对象将是具体实现。

所以如果基础对象是List<T> ,你可以很容易地说没有反思

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

所以它取决于基础类型,IEnumerable<T>只是一个界面。

答案 3 :(得分:0)

我怀疑你可以'任何IEnumerable',因为有些人可能会被懒惰评估,并且在你要求之前没有T覆盖。

但你可能会检查实现IEnumerable的集合的特殊情况 - List,Collection等 - 并以这种方式进行更改。