c# – List.Enumerator IEnumerator.Reset()方法实现
发布时间:2020-12-15 18:04:48 所属栏目:百科 来源:网络整理
导读:尽管如此, IEnumerator.Reset method should never be used我在List T中发现了方法实现的奇怪行为. 无论您如何检查.NET Framework源代码(尝试使用参考源和ILSpy),该方法都实现如下: void System.Collections.IEnumerator.Reset() { if (version != list._ve
尽管如此,
IEnumerator.Reset method should never be used我在List< T>中发现了方法实现的奇怪行为.
无论您如何检查.NET Framework源代码(尝试使用参考源和ILSpy),该方法都实现如下: void System.Collections.IEnumerator.Reset() { if (version != list._version) { ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion); } index = 0; current = default(T); } 但是,看起来这个方法根本就没有被调用过!考虑一下代码: var list = new List<int>(1) { 3 }; using (var e = list.GetEnumerator()) { Console.WriteLine(e.MoveNext()); Console.WriteLine(e.Current); ((IEnumerator)e).Reset(); Console.WriteLine(e.MoveNext()); Console.WriteLine(e.Current); } 很明显,它应该打印True和3两次.而不是结果 True 3 False 0 我错过了任何简单的解释? 解决方法
是的:你在这里装箱List.Enumerator: ((IEnumerator)e).Reset(); 这需要现有的副本并重置它 – 将原件保留为一件. 要重置实际的枚举器,你需要这样的东西: var list = new List<int>(1) { 3 }; var e = list.GetEnumerator(); // Can't use "ref" with a using statement try { Console.WriteLine(e.MoveNext()); Console.WriteLine(e.Current); Reset(ref e); Console.WriteLine(e.MoveNext()); Console.WriteLine(e.Current); } finally { e.Dispose(); } static void Reset<T>(ref T enumerator) where T : IEnumerator { enumerator.Reset(); } 这很棘手,因为它使用显式接口实现. 我没有测试过,但我认为这对你有用.显然这样做是个坏主意…… 编辑:或者,只需将您的变量类型更改为IEnumerator或IEnumerator< int>首先.然后它将被装箱一次,并且Reset方法将改变盒装值: var list = new List<int>(1) { 3 }; using (IEnumerator e = list.GetEnumerator()) { Console.WriteLine(e.MoveNext()); Console.WriteLine(e.Current); e.Reset(); Console.WriteLine(e.MoveNext()); Console.WriteLine(e.Current); } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |