无视任何理智的理由,只是出于好奇
是否可以采用任何给定的IEnumerable(T)并覆盖包含的项目?例如,给定一个IEnuemrable(String)是否可以完全替换IEnumerable中的所有字符串?
答案 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
强制执行。只要集合保持不变,枚举器仍然有效。如果对集合进行了更改,例如添加,修改或删除元素,则枚举数将无法恢复,并且下一次调用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等 - 并以这种方式进行更改。