2010-03-14 35 views
5

Trong khung .net, có giao diện chung IEnumerable<T> được kế thừa từ số không IEnumerable, và cả hai đều có phương thức GetEnumerator(). Sự khác biệt duy nhất giữa hai loại GetEnumerator() là kiểu trả về. Bây giờ tôi có thiết kế tương tự, nhưng khi tôi biên dịch mã, trình biên dịch cho biết:IEnumerable.GetEnumerator() và IEnumerable <T> .GetEnumerator()

MyInterface<T>.GetItem() 'ẩn thành viên được kế thừa' MyInterface.GetItem() '. Sử dụng từ khóa mới nếu dự định ẩn.

MyInterface<T>.GetItem() trả về loại bê tông T, trong khi MyInterface.GetItem() trả về loại System.Object.

Vì vậy, tôi nghĩ nếu đội ngũ BCL biên dịch khuôn khổ .net, họ sẽ nhận được cảnh báo tương tự.

Tôi nghĩ rằng có cảnh báo trình biên dịch không tốt, bạn nghĩ sao? Và làm thế nào tôi có thể giải quyết vấn đề này? Ý tôi là tôi muốn lấy loại bê tông T khi gọi MyInterface<T>.GetItem() không chỉ là một thể hiện kiểu System.Object.

Cảm ơn trước! :-)

Bổ sung: tôi nói các giao diện theirselves: IMyInterface thừa hưởng từ IMyInterface, và cả hai đều có GetItem() phương pháp (các IMyInterface.GetItem() trả về gõ T, trong khi IMyInterface. GetItem() trả về kiểu System.Object). Vấn đề là, nếu mã của chúng tôi chỉ có hai giao diện, đó là, không có lớp bê tông có nguồn gốc nào, chúng ta sẽ gặp phải cảnh báo trình biên dịch sau khi biên dịch mã nguồn.

Trả lời

10

Chúng không phải vì chúng biên dịch một phiên bản dưới dạng triển khai phương pháp giao diện rõ ràng. Nó trông giống như thế này:

public class SomeClassThatIsIEnumerable<T> : IEnumerable<T> 
{ 
    public IEnumerator<T> GetEnumerator() 
    { 
     // return enumerator. 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return ((IEnumerable<T>)this).GetEnumerator(); 
    } 
} 

gì loại xây dựng, không có gì làm cho phương pháp GetEnumerator đầu tiên trở thành phương pháp mặc định, trong khi các phương pháp GetEnumerator khác là chỉ truy cập được nếu người gọi đầu tiên phôi SomeClassThatIsIEnumerable để loại IEnumerator, vì vậy nó tránh được vấn đề.

Edit: dựa trên việc bổ sung trên, bạn sẽ muốn sử dụng các từ khóa mới:

public interface IMyInterface 
{ 
    object GetObject(); 
} 

public interface IMyInterface<T> : IMyInterface 
{ 
    new T GetObject(); 
} 

// implementation: 

public class MyClass : IMyInterface<string> 
{ 
    public string GetObject() 
    { 
     return "howdy!"; 
    } 

    object IMyInterface.GetObject() 
    { 
     return GetObject(); 
    } 
} 
+0

Xin chào, tôi không nói điều này, vui lòng xem "Phụ trang" của tôi trong bài đăng. Cảm ơn :) –

+0

+1 mặc dù bạn không thể chỉ định cấp độ truy cập để triển khai giao diện rõ ràng – erikkallen

+0

@Dylan: Sử dụng từ khóa mới như trình biên dịch đề xuất. Xem các chỉnh sửa của tôi ở trên. –

3

Sự khác biệt là IEnumerable<T>IEnumerable là các giao diện. Trong một loại cụ thể, thực hiện cả hai giao diện, ít nhất một trong số chúng phải được thực hiện một cách rõ ràng.

Trong loại thừa kế cụ thể, bạn phải sử dụng từ khóa mới để cho biết rằng bạn muốn ghi đè phương thức từ loại cơ sở. Khi appplying từ khóa mới, phương thức này không được kế thừa. Điều này có nghĩa là myTypeInstance.Method sẽ gọi phương thức được xác định trên MyType, trong khi ((MyBaseType) myTypeInstance).Method sẽ gọi phương thức được xác định trên loại cơ sở.

public interface Interface1 { 
    object GetItem(); 
} 

public interface Interface2<T> : Interface1 { 
    T GetItem(); 
} 

public class MyBaseType : Interface1 { 
    public object GetItem() { 
     // implements Interface1.GetType() 
     return null; 
    } 
} 

public class MyType<T> : Interface1, Interface2<T> { 
    public new T GetItem() { 
     // Implements Interface2<T>.GetItem() 
     return default(T); 
    } 

    object Interface1.GetItem() { 
     // implements Interface1.GetItem() 
     return this.GetItem(); // calls GetItem on MyType 
    } 
} 

var myType = new MyType(); 
var myTypeResult = myType.GetItem(); // calls GetItem on MyType 
var myBaseTypeResult = new ((MyBaseType) myType).GetItem(); // calls GetItem on MyBaseType 
+0

Hi, trong senario của tôi, kế thừa Interface2 từ Interface1, sau đó bạn sẽ nhận được cảnh báo trình biên dịch. –

+0

Nếu không có sự khác biệt, miễn là một trong những phương pháp GetItem được thực hiện một cách rõ ràng, tức là sử dụng Interface.GetItem. – AxelEckenberger

+0

Xin chào, sẽ có một cảnh báo trình biên dịch, trừ khi tôi sử dụng từ khóa "mới". Vui lòng xem phần bổ sung của tôi trong bài đăng.:) –

Các vấn đề liên quan