gpt4 book ai didi

c# - 用 ienumerable 实现 ienumerable

转载 作者:行者123 更新时间:2023-11-30 20:46:56 31 4
gpt4 key购买 nike

在泛型集合类中用 IEnumerable (Generic) 接口(interface)实现 IEnumerable (Non-generic) 需要什么?
关于 msdn 状态的代码示例(链接 - http://msdn.microsoft.com/en-us/library/9eekhta0(v=vs.110).aspx)

public class App
{
// Excercise the Iterator and show that it's more
// performant.
public static void Main()
{
TestStreamReaderEnumerable();
TestReadingFile();
}

public static void TestStreamReaderEnumerable()
{
// Check the memory before the iterator is used.
long memoryBefore = GC.GetTotalMemory(true);

// Open a file with the StreamReaderEnumerable and check for a string.
var stringsFound =
from line in new StreamReaderEnumerable(@"c:\\temp\\tempFile.txt")
where line.Contains("string to search for")
select line;


Console.WriteLine("Found: " + stringsFound.Count());

// Check the memory after the iterator and output it to the console.
long memoryAfter = GC.GetTotalMemory(false);
Console.WriteLine("Memory Used With Iterator = \t"
+ string.Format(((memoryAfter - memoryBefore) / 1000).ToString(), "n") + "kb");
}

public static void TestReadingFile()
{
long memoryBefore = GC.GetTotalMemory(true);
StreamReader sr = File.OpenText("c:\\temp\\tempFile.txt");

// Add the file contents to a generic list of strings.
List<string> fileContents = new List<string>();
while (!sr.EndOfStream) {
fileContents.Add(sr.ReadLine());
}

// Check for the string.
var stringsFound =
from line in fileContents
where line.Contains("string to search for")
select line;

sr.Close();
Console.WriteLine("Found: " + stringsFound.Count());

// Check the memory after when the iterator is not used, and output it to the console.
long memoryAfter = GC.GetTotalMemory(false);
Console.WriteLine("Memory Used Without Iterator = \t" +
string.Format(((memoryAfter - memoryBefore) / 1000).ToString(), "n") + "kb");

}
}

// A custom class that implements IEnumerable(T). When you implement IEnumerable(T),
// you must also implement IEnumerable and IEnumerator(T).
public class StreamReaderEnumerable : IEnumerable<string>
{

private string _filePath;
public StreamReaderEnumerable(string filePath)
{
_filePath = filePath;
}


// Must implement GetEnumerator, which returns a new StreamReaderEnumerator.
public IEnumerator<string> GetEnumerator()
{
return new StreamReaderEnumerator(_filePath);
}

// Must also implement IEnumerable.GetEnumerator, but implement as a private method.
private IEnumerator GetEnumerator1()
{
return this.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator1();
}

}

// When you implement IEnumerable(T), you must also implement IEnumerator(T),
// which will walk through the contents of the file one line at a time.
// Implementing IEnumerator(T) requires that you implement IEnumerator and IDisposable.
public class StreamReaderEnumerator : IEnumerator<string>
{
private StreamReader _sr;
public StreamReaderEnumerator(string filePath)
{
_sr = new StreamReader(filePath);
}

private string _current;
// Implement the IEnumerator(T).Current publicly, but implement
// IEnumerator.Current, which is also required, privately.
public string Current
{

get
{
if (_sr == null || _current == null)
{
throw new InvalidOperationException();
}

return _current;
}
}

private object Current1
{

get { return this.Current; }
}
object IEnumerator.Current
{
get { return Current1; }
}

// Implement MoveNext and Reset, which are required by IEnumerator.
public bool MoveNext()
{

_current = _sr.ReadLine();
if (_current == null)
return false;
return true;
}

public void Reset()
{
_sr.DiscardBufferedData();
_sr.BaseStream.Seek(0, SeekOrigin.Begin);
_current = null;
}
// Implement IDisposable, which is also implemented by IEnumerator(T).
private bool disposedValue = false;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!this.disposedValue)
{
if (disposing)
{
// Dispose of managed resources.
}
_current = null;
_sr.Close();
_sr.Dispose();
}

this.disposedValue = true;
}

~StreamReaderEnumerator()
{
Dispose(false);
}
// This example displays output similar to the following:
//Found: 2
//Memory Used With Iterator = 33kb
//Found: 2
//Memory Used Without Iterator = 206kb
}

最佳答案

需要的仅仅是因为接口(interface)是如何实现的。在 .NET 1.1 中,没有泛型,所以 IEnumerable没有通用支持,只公开 object .这引入了装箱(这也是为什么编译器还支持 foreach 的基于模式的实现,独立于 IEnumerable )。在 C# 2 中,我们得到了 IEnumerable<T> .将所有类型化迭代视为非类型化是很有用的,因此:

IEnumerable<T> : IEnumerable

哪里IEnumerable<T>重新声明 GetEnumerator与通用类型一样。但是,由于这些现在是具有不同签名的不同方法,因此需要 2 种不同的实现。

关于c# - 用 ienumerable<T> 实现 ienumerable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26272638/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com