2012-02-08 42 views
15

Tôi có hai tùy chọn trong VS2010 để triển khai giao diện.Thực hiện Giao diện vs Triển khai Giao diện Rõ ràng trong C#

enter image description here

Khi tôi có giao diện IHelper.cs như sau:

public interface IHelper 
    .... 
    IEnumerable<IPort> Ports { get; } 

"Thực hiện giao diện một cách rõ ràng" cho mã này:

IEnumerable<IPort> IHelper.Ports 
    { 
     get 
     { 
      ... 
     } 
    } 

Và, "Thực hiện giao diện" mang lại cho tôi mã này:

public IEnumerable<IPort> Ports 
    { 
     get 
     { 
      ... 
     } 
    } 

Chúng giống nhau hay khác nhau? Tại sao tôi có hai tùy chọn trong việc thực hiện các giao diện trong C#?

+0

"Triển khai giao diện công khai" và "Triển khai giao diện riêng tư" có quá khó không? – PRMan

Trả lời

24

Khai báo giao diện rõ ràng có nghĩa là các thành viên giao diện không có sẵn trên các loại khác với giao diện, do đó, việc triển khai các loại sẽ cần phải được truyền tới giao diện trước khi truy cập công khai.

Ngụ ý, cách tiêu chuẩn mà hầu hết các giao diện được triển khai, cho thấy các mục giao diện trên API công khai của loại triển khai.

Lý do chính cho định nghĩa giao diện rõ ràng là tránh xung đột đặt tên nếu bạn tình cờ triển khai hai giao diện chứa các phương thức có cùng chữ ký ... định nghĩa rõ ràng cho phép trình biên dịch giữ chữ ký riêng biệt đủ để giải quyết.

Lý do thứ hai hỗ trợ bảo trì mã, theo đề xuất của XenoPuTtSs trong các nhận xét, là định nghĩa rõ ràng sẽ kích hoạt lỗi trình biên dịch trên các loại triển khai nếu chữ ký phương thức bị xóa. Khi triển khai ngầm, việc xóa một phương thức khỏi giao diện sẽ khiến phương thức này trở thành thành viên thông thường của bất kỳ loại nào - nghĩa là bạn cần phải tìm kiếm thủ công để triển khai phương pháp hiện tại không còn tồn tại.

+2

cũng (không phải là lý do chính) khi giao diện thay đổi (giống như phương thức được loại bỏ hoặc thay đổi) trình biên dịch sẽ ném một lỗi trên các lớp được định nghĩa rõ ràng giao diện bởi vì các phương thức đó không còn trên giao diện. Đây là một cách hữu ích (IMHO) để định vị mã không sử dụng từ các dự án lớn. – XenoPuTtSs

+0

@XenoPuTtSs Điểm tốt, tôi đã sửa đổi câu trả lời của tôi để bao gồm điều này. –

5

Lớp học triển khai giao diện có thể triển khai rõ ràng thành viên của giao diện đó. Khi một thành viên được triển khai một cách rõ ràng, nó không thể được truy cập thông qua một cá thể lớp, mà chỉ thông qua một cá thể của giao diện.

// explicit1.cs 
interface IDimensions 
{ 
    float Length(); 
    float Width(); 
} 

class Box : IDimensions 
{ 
    float lengthInches; 
    float widthInches; 

public Box(float length, float width) 
{ 
    lengthInches = length; 
    widthInches = width; 
} 
// Explicit interface member implementation: 
float IDimensions.Length() 
{ 
    return lengthInches; 
} 
// Explicit interface member implementation: 
float IDimensions.Width() 
{ 
    return widthInches;  
} 

public static void Main() 
{ 
    // Declare a class instance "myBox": 
    Box myBox = new Box(30.0f, 20.0f); 
    // Declare an interface instance "myDimensions": 
    IDimensions myDimensions = (IDimensions) myBox; 
    // Print out the dimensions of the box: 
    /* The following commented lines would produce compilation 
    errors because they try to access an explicitly implemented 
    interface member from a class instance:     */ 
    //System.Console.WriteLine("Length: {0}", myBox.Length()); 
    //System.Console.WriteLine("Width: {0}", myBox.Width()); 
    /* Print out the dimensions of the box by calling the methods 
    from an instance of the interface:       */ 
    System.Console.WriteLine("Length: {0}", myDimensions.Length()); 
    System.Console.WriteLine("Width: {0}", myDimensions.Width()); 
} 
} 

Triển khai giao diện rõ ràng cũng cho phép lập trình viên kế thừa hai giao diện chia sẻ cùng tên thành viên và cung cấp cho từng thành viên giao diện một triển khai riêng biệt. Ví dụ này hiển thị kích thước của một hộp ở cả đơn vị số liệu và tiếng Anh. Lớp Box kế thừa hai giao diện IEnglishDimensions và IMetricDimensions, đại diện cho các hệ thống đo lường khác nhau. Cả hai giao diện đều có tên thành viên giống nhau, Độ dài và Chiều rộng.

nhìn vào ví dụ

// explicit2.cs 
// Declare the English units interface: 
interface IEnglishDimensions 
{ 
    float Length(); 
    float Width(); 
} 
// Declare the metric units interface: 
interface IMetricDimensions 
{ 
    float Length(); 
    float Width(); 
} 
// Declare the "Box" class that implements the two interfaces: 
// IEnglishDimensions and IMetricDimensions: 
class Box : IEnglishDimensions, IMetricDimensions 
{ 
    float lengthInches; 
    float widthInches; 
public Box(float length, float width) 
    { 
    lengthInches = length; 
    widthInches = width; 
    } 
// Explicitly implement the members of IEnglishDimensions: 
float IEnglishDimensions.Length() 
{ 
    return lengthInches; 
} 
float IEnglishDimensions.Width() 
{ 
    return widthInches;  
} 
// Explicitly implement the members of IMetricDimensions: 
float IMetricDimensions.Length() 
{ 
    return lengthInches * 2.54f; 
} 
float IMetricDimensions.Width() 
{ 
    return widthInches * 2.54f; 
} 
public static void Main() 
{ 
    // Declare a class instance "myBox": 
    Box myBox = new Box(30.0f, 20.0f); 
    // Declare an instance of the English units interface: 
    IEnglishDimensions eDimensions = (IEnglishDimensions) myBox; 
    // Declare an instance of the metric units interface: 
    IMetricDimensions mDimensions = (IMetricDimensions) myBox; 
    // Print dimensions in English units: 
    System.Console.WriteLine("Length(in): {0}", eDimensions.Length()); 
    System.Console.WriteLine("Width (in): {0}", eDimensions.Width()); 
    // Print dimensions in metric units: 
    System.Console.WriteLine("Length(cm): {0}", mDimensions.Length()); 
    System.Console.WriteLine("Width (cm): {0}", mDimensions.Width()); 
} 
} 

để biết thêm chi tiết xem xét điều này article

+1

Tốt nhất nên bao gồm các phần thông tin có liên quan từ bài viết trong câu trả lời, các liên kết là không ổn định và có thể không tồn tại miễn là câu trả lời. Nếu liên kết đó thất bại, câu trả lời của bạn sẽ không giúp được gì. –

+0

vâng tôi nghiêm túc với bạn. – Serghei

6

Họ là hoàn toàn khác nhau. Nếu bạn triển khai giao diện một cách rõ ràng, bạn sẽ chỉ có thể tham chiếu các thành viên giao diện bằng cách tham chiếu giao diện đó. Đoạn mã sau thể hiện ý tưởng.

public interface IFoo { 
    String Bar { get; set; } 
} 
public class ImplicitFoo : IFoo { 
    public string Bar {get;set;} 
} 
public class ExplicitFoo : IFoo { 
    private String _Bar; 
    string IFoo.Bar { 
     get { 
      return _Bar; 
     } 
     set { 
      _Bar = value; 
     } 
    } 
} 
public class Test { 
    public void Test() { 
     var iml = new ImplicitFoo(); 
     // Works fine 
     Console.WriteLine(iml.Bar); 
     var expl = new ExplicitFoo(); 
     var fooInterface = (IFoo)expl; 
     // Works fine 
     Console.WriteLine(fooInterface.Bar); 
     // Throws compile time exception 
     Console.WriteLine(expl.Bar); 
    } 
} 
Các vấn đề liên quan