2009-07-23 37 views
8

Tôi đang cố gắng lấy mã sau đây để biên dịch nhưng tôi nhận được lỗi trong VS2008. Bất cứ ai có thể cho tôi biết nơi tôi đang đi sai?IEnumerable <T> in C#

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace dummy 
{ 
    public class NaturalNumbersSequence : IEnumerable<int> 
    { 
     public IEnumerator<int> GetEnumerator() 
     { 
      for (int i = 1; i <= 1000; i++) 
       yield return i; 
     } 

     IEnumerator IEnumerable.GetEnumerator() 
     { 
      for (int i = 1; i <= 1000; i++) 
       yield return i; 
     } 
    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      foreach (int i in new NaturalNumbersSequence()) 
       Console.WriteLine(i); 
     } 
    } 
} 
+12

Lưu ý, bạn cũng nên đăng các thông báo lỗi mà bạn đang nhận được. –

Trả lời

24

Vâng, lỗi biên dịch đầu tiên tôi nhận được là nó than phiền rằng:

Sử dụng các loại chung 'System.Collections.Generic.IEnumerator' đòi hỏi '1' đối số loại

Đây là trên đường dây 16, điều này một:

IEnumerator IEnumerable.GetEnumerator() 

Sửa rằng bằng cách thêm một chúng tôi chỉ thị ing cho không gian tên System.Collections (mẹo: đặt con trỏ ngay sau IEnumerator, trên r ở cuối từ và nhấn Ctrl +. (ctrl + dấu chấm), bạn nên thêm "using System.Collections"; chỉ thị, làm điều đó).

Sau đó, nó biên dịch và chạy. Điều đó phù hợp với những gì bạn mong đợi? Ngoài ra, lưu ý rằng bạn nên luôn luôn đăng các thông báo lỗi thực tế mà bạn đang nhận được, bằng cách này chúng tôi không sủa cây sai nếu có điều gì đó sai với mã của bạn mà chúng ta không nhìn thấy ngay từ cái nhìn đầu tiên.

Ngoài ra, bạn có thể đơn giản hóa thực hiện này rất phổ biến của IEnumerable<T> bằng cách gọi một trong những phương pháp từ người khác, vì thế tôi sẽ đơn giản hóa việc thực hiện các phương pháp thứ hai như thế này:

IEnumerator IEnumerable.GetEnumerator() 
{ 
    return GetEnumerator(); // this will return the one 
          // available through the object reference 
          // ie. "IEnumerator<int> GetEnumerator" 
} 

cách này bạn chỉ thực hiện mã điều tra thực tế một lần.

Và cuối cùng cũng thấy Earwicker 's answer là tốt, nó cho thấy một cách tốt hơn (theo ý kiến ​​của tôi ít nhất) để viết toàn bộ mã này.

+1

+1. Phần cuối cùng về việc sử dụng lại một cách thực hiện của điều tra viên ở bên kia là đóng băng trên bánh. –

+0

tại sao có 2 lần thực hiện điều tra viên ở nơi đầu tiên? – fcuk112

9

Không chắc chắn lý do tại sao bạn gặp phải lỗi, nhưng điều này sẽ không đơn giản hơn?

public static class NumbersSequence 
{ 
    public static IEnumerable<int> Naturals 
    { 
     get 
     { 
      for (int i = 1; i <= 1000; i++) 
       yield return i; 
     } 
    } 
} 

class Program 
{ 
    public static void Main(string[] args) 
    { 
     foreach (int i in NumbersSequence.Naturals) 
      Console.WriteLine(i); 
    } 
} 
+5

Và tại sao dừng lại ở một ngàn? –

+12

Mọi người đều biết rằng con số trên 1000 cao bất thường. –

+2

Đối với tôi, sự khác biệt giữa các số "thông thường" và "lớn" là hai mươi nghìn. Tôi đoán đó là một điều "thực hiện". –

4

Hơi lạc đề, nhưng có lẽ thú vị để xem là phương pháp này:

public static class NumbersSequence 
{ 
    public static IEnumerable<int> Naturals 
    { 
     get 
     { 
      int i = 0; 
      while(true) 
       yield return i++; 
     } 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     foreach (int i in NumbersSequence.Naturals.Take(1000)) 
      Console.WriteLine(i); 
    } 
} 

C# 3.0 afaik. Chú ý đến vòng lặp dường như vô tận trong getter, và gọi đến Take (1000). Với phương pháp này, bây giờ bạn có một chuỗi 'vô tận' các số tự nhiên (vô tận cho đến khi giá trị cực đại của một int). Nó sẽ không bị mắc kẹt, miễn là bạn nói với nó để có một số tiền cụ thể.

KHUYẾN CÁO: Hầu hết mã được mượn từ câu trả lời của Earwicker.

+1

Vậy 'i' trong 'Naturals.get' là gì? –

+1

Luôn luôn tốt đẹp để xem "vô hạn" vòng trong hành động. –

+1

Như Pavel nhận thấy, bạn đang thiếu khởi tạo và tăng của i. –

2

Lasse có câu trả lời đúng, và tôi biết điều này là học tập mã, nhưng vì lợi ích của việc đẩy mạnh học tập của bạn tôi muốn đề cập đến hai điều:

  1. Enumerable.Range()
  2. Hãy dành thời gian để suy nghĩ về vấn đề này triển khai:

.

public class NaturalNumbersSequence : IEnumerable<int> 
{ 
    public IEnumerator<int> GetEnumerator() 
    { 
     for (int i=0 i <= int.MaxValue;i++) 
      yield return i; 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     for (int i=0 i <= int.MaxValue;i++) 
      yield return i; 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     foreach (int i in new NaturalNumbersSequence().TakeWhile(i => i<=1000)) 
      Console.WriteLine(i); 
    } 
} 
Các vấn đề liên quan