Các ví dụ mã sau minh họa làm thế nào để viết một lớp tổng quát mà có thể được sử dụng với foreach. Lớp học là một tokenizer chuỗi, tương tự như chức năng strtok_s C run-time.
Trong ví dụ sau đây, Tokens chia các câu "Đây là một câu ví dụ." vào thẻ bằng cách sử dụng '' và '-' là dấu phân cách, và liệt kê những thẻ bài bằng foreach:
Tokens f = new Tokens("This is a sample sentence.", new char[] {' ','-'});
foreach (string item in f)
{
System.Console.WriteLine(item);
}
Trong nội bộ, Tokens sử dụng một mảng, mà thực hiện IEnumerator và IEnumerable chính nó. Ví dụ mã có thể đã sử dụng phương pháp liệt kê của mảng như là của riêng nó, nhưng mà có thể đã thất bại nhằm mục đích của ví dụ này.
Trong C#, nó không phải là hoàn toàn cần thiết để một class collections để kế thừa từ IEnumerable và IEnumerator để tương thích với foreach. Khi lớp có GetEnumerator yêu cầu, MoveNext, Reset, và các thành viên hiện tại, nó sẽ làm việc với foreach. Bỏ qua các interface có lợi thế là cho phép bạn xác định kiểu trả về của hiện tại để được nhiều hơn so với đối tượng cụ thể, cung cấp kiểu an toàn.
Ví dụ, bắt đầu với ví dụ mã trước đó trong chủ đề này, thay đổi những dòng này:
// No longer inherits from IEnumerable:
public class Tokens
// Doesn't return an IEnumerator:
public TokenEnumerator GetEnumerator()
// No longer inherits from IEnumerator:
public class TokenEnumerator
// Type-safe: returns string, not object:
public string Current
Bây giờ, bởi vì trả về một chuỗi hiện tại, các trình biên dịch có thể phát hiện khi một kiểu không tương thích được sử dụng trong một câu lệnh foreach:
// Error: cannot convert string to int:
foreach (int item in f)
Những bất lợi của IEnumerable và IEnumerator bỏ qua là các class collections không còn tương thích với các câu lệnh foreach, hoặc tương đương, của các ngôn ngữ khác ngôn ngữ thông dụng khi chạy tương thích.
Bạn có thể có tốt nhất của cả hai thế giới, kiểu an toàn trong C# và khả năng tương tác với các ngôn ngữ khác ngôn ngữ phổ biến thời gian chạy tương thích, do thừa kế từ IEnumerable và IEnumerator và sử dụng giao diện thực hiện rõ ràng như thể hiện trong ví dụ sau đây.
using System.Collections;
// Declare the Tokens class:
public class Tokens : IEnumerable
{
private string[] elements;
Tokens(string source, char[] delimiters)
{
// Parse the string into tokens:
elements = source.Split(delimiters);
}
// IEnumerable Interface Implementation:
// Declaration of the GetEnumerator() method
// required by IEnumerable
public IEnumerator GetEnumerator()
{
return new TokenEnumerator(this);
}
// Inner class implements IEnumerator interface:
private class TokenEnumerator : IEnumerator
{
private int position = -1;
private Tokens t;
public TokenEnumerator(Tokens t)
{
this.t = t;
}
// Declare the MoveNext method required by IEnumerator:
public bool MoveNext()
{
if (position < t.elements.Length - 1)
{
position++;
return true;
}
else
{
return false ;
}
}
// Declare the Reset method required by IEnumerator:
public void Reset()
{
position = -1;
}
// Declare the Current property required by IEnumerator:
public object Current
{
get
{
return t.elements[position];
}
}
}
// Test Tokens, TokenEnumerator
static void Main()
{
// Testing Tokens by breaking the string into tokens:
Tokens f = new Tokens("This is a sample sentence.", new char[] {' ','-'});
foreach (string item in f)
{
System.Console.WriteLine(item);
}
}
}
/* Output:
This
is
a
sample
sentence.
*/
DangTrung.
Không có nhận xét nào:
Đăng nhận xét