Frage

Ich habe ein sehr einfaches Szenario: ein " Mensch " a sein kann " Kunden " oder " Mitarbeiter " eines Unternehmens.

A " Mensch " kann telefonisch mit der " Anruf " Methode aufgerufen werden.

Je nachdem, welche Rolle des " Mensch " spielt in dem Kontext des Anrufs , z.B. die Ankündigung eines neuen Produkts oder die Ankündigung einer Änderung in der Organisation, wir sollten entweder die Telefonnummer für die „ Kunden “ Rolle oder die für die „ Mitarbeiter bereitgestellt ein bereitgestellt verwenden “Rolle.

Hier ist eine Summe-up der Situation:

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
    }
}

Aber dieser Code doe nicht kompiliert und erzeugt die Fehler:

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()'

Ist dieses Szenario eine Chance hat in C # in einer anderen Art und Weise implementierbar zu sein oder muss ich einen anderen Entwurf finden?

Wenn ja, welche Alternativen schlagen Sie vor?

Vielen Dank im Voraus für Ihre Hilfe.

War es hilfreich?

Lösung

Ihr Ziel ist nicht sinnvoll.

Weder ICustomer noch IEmployee definiert ein Call() Verfahren; sie nur die Methode von der gleichen Schnittstelle erben. Ihre Both Klasse implementiert die gleiche Schnittstelle zweimal.
Jeder möglicher Call Anruf wird immer anrufen IPerson.Call; es gibt keine IL-Instruktionen, die speziell ICustomer.Call oder IEmployee.Call nennen.

Unter Umständen können Sie diese lösen, indem sie explizit Call in beiden Kindern Schnittstellen neu zu definieren, aber ich sehr empfehlen, dass man sich nur verschiedene Namen geben.

Andere Tipps

Neben den Themen SLaks genau darauf hingewiesen, ...

Get von IPerson befreien und IContactable mit einem Verfahren zur Contact() schaffen, dann zwei konkreten Typen erstellen Customer und Employee genannt, dass IContactable implementieren. Dann, wenn Sie Kontakt jemanden brauchen, können Sie Ihre IContactable.Contact() Methode aufrufen, wie da in der Lage gewünschten Kontakt zu machen könnte erweitern, während IPerson etwas abstrakt ist.

Ich lief in diesen selbst.

Sie können das Problem lösen, indem Zusammensetzung mit:

interface IPerson
{
    void Call();
}

interface ICustomer : IPerson
{
}

interface IEmployee : IPerson
{
}

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

Das geht davon aus, dass die oben Mitarbeiter in der beide Klasse ist eine kundenspezifische Implementierung von IEmployee und basierten auf einem Both Objekt aufgebaut ist.

Aber es hängt davon ab, wie Sie planten die beiden Klassen.
Wenn Sie wollten die beiden Klassen wie folgt verwenden:

((IEmployee)both).Call();

Dann stattdessen können Sie diese verwenden:

both.Employee.Call();

Ich habe Interesse an Ihrer Eingabe mit meiner Lösung ...

Ich habe explizite Implementierung viel mit Zusammensetzungen, wenn ich möchte einen Controller einige Eigenschaften oder Methoden, die auf meiner Klasse zuzugreifen, die von einer normalen Nutzung der Klasse versteckt werden sollte ...

Also, um die Lage sein, mehrere Implementierung von IPerson zu haben, in diesem Beispiel würde ich Generika, in der Lage sein, die IPerson Schnittstelle von einem Kunden an einen Mitarbeiter zu spalten

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 
    }
} 

Sie können dies nicht tun, weil die Call-Methode aus der IPerson Schnittstelle in den beiden Fällen kommt. So Sie versuchen, die Call-Methode zweimal zu definieren. Ich schlage vor, Sie ICustomer und IEmployee Schnittstelle in der Klasse zu ändern und die Call-Methode in dieser Klasse zu definieren:

interface IPerson
{
    void Call();
}

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

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

Ich weiß nicht, ob das hilft oder nicht, aber man könnte es ein Schuss.

//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 { } 
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top