簡體   English   中英

顯式接口實現限制

[英]Explicit interface implementation limitation

我有一個非常簡單的場景:“ ”可以是公司的“ 客戶 ”或“ 員工 ”。

一個“ ”,可以通過電話與“ 呼叫 ”的方法被調用。

根據“ ”在通話環境中扮演的角色,例如新產品的公告或組織變更的公告,我們應該使用為“ 客戶 ”角色提供的電話號碼或提供的電話號碼為“ 員工 ”角色。

以下是對情況的總結:

interface IPerson
{
    void Call();
}

interface ICustomer : IPerson
{
}

interface IEmployee : IPerson
{
}

class Both : ICustomer, IEmployee
{
    void ICustomer.Call()
    {
        // Call to external phone number
    }

    void IEmployee.Call()
    {
        // Call to internal phone number
    }
}

但是這段代碼不能編譯並產生錯誤:

error CS0539: 'ICustomer.Call' in explicit interface declaration is not a member of interface
error CS0539: 'IEmployee.Call' in explicit interface declaration is not a member of interface
error CS0535: 'Both' does not implement interface member 'IPerson.Call()'

這種情況是否有機會以不同的方式在C#中實現,還是我必須找到另一種設計?

如果是這樣,你建議用什么替代品?

在此先感謝您的幫助。

你的目標沒有意義。

ICustomerIEmployee都沒有定義Call()方法; 他們只是從同一個接口繼承該方法。 您的Both類兩次實現相同的接口。
任何可能的Call呼叫將始終呼叫IPerson.Call ; 沒有專門調用ICustomer.CallIEmployee.Call IL指令。

您可以通過在兩個子接口中顯式重新定義Call來解決此問題,但我強烈建議您只是給它們不同的名稱。

我自己也碰到了這個。

您可以使用組合來解決問題:

interface IPerson
{
    void Call();
}

interface ICustomer : IPerson
{
}

interface IEmployee : IPerson
{
}

class Both
{
    public ICustomer Customer { get; }
    public IEmployee Employee { get; }
}

以上假設Both類中的Employee是IEmployee的自定義實現,並且是基於Both對象構造的。

但這取決於你打算如何使用Both類。
如果你想像這樣使用Both類:

((IEmployee)both).Call();

然后你可以使用這個:

both.Employee.Call();

我對我的解決方案的輸入感興趣...

當我希望控制器訪問我的類中的一些屬性或方法時,我使用了很多組合的顯式實現,這些屬性或方法應該隱藏在類的常規用法中...

因此,為了能夠多次實現IPerson,在本例中,我將使用泛型,以便能夠將IPerson接口從客戶拆分為員工

interface IPerson<T>
{
    void Call();
}

interface ICustomer : IPerson<ICustomer>
{
}

interface IEmployee : IPerson<IEmployee>
{
}

class Both : ICustomer, IEmployee
{
    void IPerson<ICustomer>.Call()
    {
        // Call to external phone number 
    }

    void IPerson<IEmployee>.Call()
    {
        // Call to internal phone number 
    }
} 

除了SLaks准確指出的問題......

擺脫IPerson並使用Contact()方法創建IContactable ,然后創建兩個實現IContactable稱為CustomerEmployee具體類型。 然后,當你需要聯系某人時,你可以根據需要調用你的IContactable.Contact()方法,因為能夠進行聯系可以擴展,而IPerson有點抽象。

你不能這樣做,因為Call方法來自兩種情況下的IPerson接口。 因此,您嘗試兩次定義Call方法。 我建議您將ICustomer和IEmployee接口更改為類,並在此類中定義Call方法:

interface IPerson
{
    void Call();
}

class Customer : IPerson
{
    public void Call()
    {
    }
}

class Employee : IPerson
{
    public void Call()
    {
    }
}

我不知道這是否有幫助,但你可以試一試。

//ran in linqpad c# program mode, you'll need to provide an entry point.....
void Main()
{
    IPerson x;
    x = new Both(new Employee());
    x.call(); //outputs "Emplyee"
    x = new Both(new Customer());
    x.call(); //outputs "Customer"
}

class Customer :  ICustomer
{
    public void call() {"Customer".Dump();}
}
class Employee :  IEmployee
{
    public void call() {"Employee".Dump();}
}
class Both : IPerson
{
     private IPerson Person { get; set; }
     public Both(IPerson person)
     {
         this.Person = person;
     }
     public void call()
     {
        Person.call();
     }
} 
interface IPerson { void call(); }  
interface ICustomer : IPerson { } 
interface IEmployee : IPerson { } 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM