2009-04-03 36 views

Trả lời

13

Một khía cạnh khác của việc này:

Nếu bạn ngầm thực hiện, nó có nghĩa là các thành viên giao diện có thể truy cập đến người dùng lớp học của bạn mà không cần phải bỏ qua.

Nếu đã thực hiện rõ ràng, khách hàng sẽ phải đưa lớp của bạn lên giao diện trước khi có thể truy cập vào các thành viên. Dưới đây là một ví dụ về thực hiện rõ ràng:

interface Animal 
{ 
    void EatRoots(); 
    void EatLeaves(); 
} 

interface Animal2 
{ 
    void Sleep(); 
} 


class Wombat : Animal, Animal2 
{ 
    // Implicit implementation of Animal2 
    public void Sleep() 
    { 
    } 

    // Explicit implementation of Animal 
    void Animal.EatRoots() 
    { 

    } 

    void Animal.EatLeaves() 
    { 
    } 

} 

mã khách hàng của bạn

Wombat w = new Wombat(); 
w.Sleep(); 
w.EatRoots(); // This will cause a compiler error because it's explicitly implemented 
((Animal)w).EatRoots(); // This will compile 
0

Ở đây bạn đi, trực tiếp từ MSDN

0

Sự khác biệt là bạn có thể kế thừa một lớp từ một số giao diện. Các giao diện này có thể có các chữ ký Phương thức giống nhau. Triển khai rõ ràng cho phép bạn thay đổi triển khai của mình theo Giao diện được sử dụng để gọi nó.

4

Rõ ràng sẽ đặt IInterfaceName. ở phía trước của tất cả các triển khai giao diện. Sẽ rất hữu ích nếu bạn cần triển khai hai giao diện chứa tên/chữ ký xung đột.

Thông tin thêm here.

10

IDE cung cấp cho bạn tùy chọn để thực hiện một trong hai việc - sẽ không bình thường khi thực hiện cả hai. Với việc triển khai rõ ràng, các thành viên không nằm trong API công khai (chính); điều này rất tiện lợi nếu giao diện không được gắn trực tiếp với mục đích của đối tượng. Ví dụ, các thành viên ICustomTypeDescriptor không phải là tất cả những gì hữu ích cho người gọi thông thường - chỉ với một số mã rất cụ thể, vì vậy không có mục đích có chúng trên API công cộng gây ra sự lộn xộn.

này cũng rất hữu ích nếu:

  • có sự mâu thuẫn giữa Foo phương pháp của một giao diện và Foo phương pháp loại của riêng bạn, và họ có nghĩa là những thứ khác nhau
  • có sự mâu thuẫn chữ ký giữa các giao diện khác

Ví dụ điển hình của điểm cuối cùng là IEnumerable<T>, có phương pháp GetEnumerator() ở hai cấp trong phân cấp giao diện - điều này thường được sử dụng ement phiên bản đã nhập (IEnumerator<T>) bằng cách sử dụng triển khai ngầm định và phiên bản chưa được phân loại (IEnumerator) bằng cách sử dụng triển khai rõ ràng.

+1

Triển khai rõ ràng cũng hữu ích khi lớp của bạn cần triển khai giao diện nội bộ mà bạn không muốn xuất công khai khỏi hội đồng của mình. – Dave

1

Rõ ràng thực hiện đặt tên đầy đủ vào tên hàm xem xét mã này

public interface IamSam 
    { 
     int foo(); 
     void bar(); 
    } 

    public class SamExplicit : IamSam 
    { 
     #region IamSam Members 

     int IamSam.foo() 
     { 
      return 0; 
     } 

     void IamSam.bar() 
     { 

     } 

     string foo() 
     { 
      return ""; 
     } 
     #endregion 
    } 

    public class Sam : IamSam 
    { 
     #region IamSam Members 

     public int foo() 
     { 
      return 0; 
     } 

     public void bar() 
     { 

     } 

     #endregion 
    } 

IamSam var1; 
var1.foo() returns an int. 
SamExplicit var2; 
var2.foo() returns a string. 
(var2 as IamSam).foo() returns an int. 
0

Explicit giao diện thực hiện, nơi thực hiện được ẩn trừ khi bạn cast một cách rõ ràng, rất hữu ích nhất khi giao diện trực giao với chức năng lớp. Đó là để nói, hành vi không liên quan. Ví dụ, nếu lớp của bạn là Person và giao diện là ISerializable, nó không có ý nghĩa nhiều cho một người nào đó đối phó với các thuộc tính Person để thấy một cái gì đó lạ gọi là 'GetObjectData' thông qua Intellisense. Do đó, bạn có thể muốn triển khai giao diện một cách rõ ràng.

Mặt khác, nếu lớp người của bạn xảy ra để thực hiện IAddress, nó làm cho cảm giác hoàn hảo để xem các thành viên như AddressLine1, ZipCode vv trên cá thể cá nhân trực tiếp (thực hiện ngầm).

6

Đây là sự khác biệt trong tiếng Anh đơn giản:

Giả sử bạn có một giao diện Machine, trong đó có một chức năng Run(), và một giao diện Animal mà còn có một chức năng gọi là Run(). Tất nhiên, khi một cỗ máy chạy, chúng ta đang nói về nó bắt đầu, nhưng khi một con vật chạy, chúng ta đang nói về nó di chuyển xung quanh. Vì vậy, điều gì sẽ xảy ra khi bạn có một đối tượng, hãy gọi nó là Aibo, cả hai là số Machine và một số Animal? (Aibo là một con chó cơ khí, bằng cách này.) Khi Aibo chạy, anh ta bắt đầu lên, hoặc không di chuyển xung quanh? Dứt khoát thực hiện một giao diện cho phép bạn thực hiện điều đó khác biệt:

interface Animal 
{ 
    void Run(); 
} 
interface Machine 
{ 
    void Run(); 
} 

class Aibo : Animal, Machine 
{ 
    void Animal.Run() 
    { 
     System.Console.WriteLine("Aibo goes for a run."); 
    } 
    void Machine.Run() 
    { 
     System.Console.WriteLine("Aibo starting up."); 
    } 
} 
class Program 
{ 
    static void Main(string[] args) 
    { 
     Aibo a = new Aibo(); 
     ((Machine)a).Run(); 
     ((Animal)a).Run(); 
    } 
} 

Việc nắm bắt ở đây là tôi không thể chỉ đơn giản là gọi a.Run() vì cả hai hiện thực của tôi về chức năng được gắn một cách rõ ràng để một giao diện. Điều đó có ý nghĩa, bởi vì nếu không thì người khiếu nại sẽ biết cái nào để gọi? Thay vào đó, nếu tôi muốn gọi hàm Run() trên trực tiếp Aibo của mình, tôi sẽ phải cũng triển khai chức năng đó mà không có giao diện rõ ràng.

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