6

私には非常に単純なシナリオがあります。「人」は会社の​​「顧客」または「従業員」になることができます。

人」は「電話」方式で電話でかけることができます。

新製品の発表や組織変更の発表など、通話のコンテキストで「」が果たす役割に応じて、「顧客」の役割に提供された電話番号または提供された電話番号のいずれかを使用する必要があります。 「従業員」の役割。

これが状況の要約です:

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#で別の方法で実装できる可能性がありますか、それとも別のデザインを見つける必要がありますか?

もしそうなら、あなたはどのような選択肢を提案しますか?

よろしくお願いします。

4

6 に答える 6

9

あなたの目的は意味がありません。

メソッドを定義するICustomerこともIEmployee、定義することもありません。Call()同じインターフェースからメソッドを継承するだけです。クラスBothは同じインターフェースを2回実装します。
可能なCall呼び出しは常にIPerson.Call;を呼び出します。ICustomer.Callまたはを具体的に呼び出すIL命令はありませんIEmployee.Call

Call両方の子インターフェースで明示的に再定義することでこれを解決できる場合がありますが、それらに異なる名前を付けることを強くお勧めします。

于 2010-12-07T17:51:11.943 に答える
2

私のソリューションでのあなたの意見に興味があります...

クラスの通常の使用から隠されるべきクラスのいくつかのプロパティまたはメソッドにコントローラーがアクセスするようにしたい場合は、コンポジションで明示的な実装を頻繁に使用しました...

したがって、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 
    }
} 
于 2012-06-21T18:29:15.907 に答える
1

問題は別として、SLaksは正確に指摘しました...

を取り除き、のメソッドを使用してIPerson作成してから、とを実装する2つの具象型を作成します。そうすれば、誰かに連絡する必要があるときはいつでも、連絡をとることができるので、必要に応じてメソッドを呼び出すことができますが、少し抽象的です。IContactableContact()CustomerEmployeeIContactableIContactable.Contact()IPerson

于 2010-12-07T17:59:15.710 に答える
1

私はこれに自分で遭遇しました。

コンポジションを使用して問題を解決できます。

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();
于 2012-05-08T21:19:22.550 に答える
0

2つのケースでは、CallメソッドがIPersonインターフェイスから取得されるため、これを行うことはできません。したがって、Callメソッドを2回定義しようとします。ICustomerおよびIEmployeeインターフェイスをクラスに変更し、このクラスでCallメソッドを定義することをお勧めします。

interface IPerson
{
    void Call();
}

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

class Employee : IPerson
{
    public void Call()
    {
    }
}
于 2010-12-07T17:59:42.450 に答える
0

これが役立つかどうかはわかりませんが、試してみることができます。

//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 { } 
于 2010-12-07T18:31:18.057 に答える