Laden...

Implementierung von mehreren Interfaces bei Namenskollisionen

Erstellt von sane vor einem Jahr Letzter Beitrag vor einem Jahr 253 Views
S
sane Themenstarter:in
40 Beiträge seit 2022
vor einem Jahr
Implementierung von mehreren Interfaces bei Namenskollisionen

Servus zusammen,

ich arbeite gerade das Pdf von Uni Trier durch. Jetzt hab ich aber ein Problem.

Wenn Eigenschaften aus einem Interface implementiert werden, dann sollten sie den Zugriffsmodifizierer public erhalten. Wenn ich die Eigenschaften automatisch von VS implementieren lasse, dann bekomme ich nur eine Eigenschaft, wie folgt.


interface ITest1
    {
        string Name { get; set; }
    }

    interface ITest2
    {
        string Name { get; set; }
    }

    class TestClass : ITest1, ITest2
    {
        public string Name { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
    }

Damit ich sie aber separat ansprechen kann müssen sie mit dem Interface Namen angesprochen werden, wie folgt.


interface ITest1
    {
        string Name { get; set; }
    }

    interface ITest2
    {
        string Name { get; set; }
    }

    class TestClass : ITest1, ITest2
    {
        string ITest1.Name { get; set; }

        string ITest2.Name { get; set; }

        public TestClass(string nameAlpha, string nameBeta)
        {
            
        }
    }

Meine Frage lautet nun, wenn es zu NamenKollisionen kommt, wie spreche ich diese Eigenschaften an, so dass ich sie im Konstruktor initialisieren kann und von ausserhalb der zugreifen?
Muss da immer eine Variable des Interfaces erstellt werden, um von aussen zuzugreifen, wie folgt?


static void Main(string[] args)
        {
            ITest1 test1 = new TestClass();
            ITest2 test2 = new TestClass();

            Console.WriteLine(test1.Name);
            Console.WriteLine(test2.Name);


            Console.ReadKey();
        }

danke für eure Hilfe im Voraus!

2.079 Beiträge seit 2012
vor einem Jahr

TestClass test = new TestClass();
Console.WriteLine(((ITest1)test).Name);
Console.WriteLine(((ITest2)test).Name);

// ITest1 test1 = (ITest1)test;
// ITest2 test2 = (ITest2)test;
// Hier brauchst Du den Cast nicht, das passiert automatisch (danke Abt, für die Korrektur)
ITest1 test1 = test;
ITest2 test2 = test;
Console.WriteLine(test1.Name);
Console.WriteLine(test2.Name);

Andere Wege gibt es nicht, zumindest keine, die nicht weit über jeden vernünftigen Nutzen hinaus gehen würden.
Und das Features heißt übrigens Explicit Interface Implementation

16.828 Beiträge seit 2008
vor einem Jahr

IIRC brauchst den Cast nicht mal.


ITest1 test1 = test;
ITest2 test2 = test;

2.079 Beiträge seit 2012
vor einem Jahr

Stimmt 😁
Ich schreibe meistens so:


var test1 = (ITest1)test;
var test2 = (ITest2)test;

Da braucht man das natürlich, aber das habe ich dann - der Klarheit wegen - nachträglich nochmal ergänzt.

Danke für die Korrektur

PS: Ich hab's oben aktualisiert.

S
sane Themenstarter:in
40 Beiträge seit 2022
vor einem Jahr

Danke für Eure Antworten!

Darf ich noch eine Frage stellen. Ich hab versucht im Konstruktor die Instanzen zu erstellen und in eine public InstanzVariable gesteckt, um sie von aussen aufzurufen. Finge weg?? oder machbar? Compiler sagt ja?


interface ITest1
    {
        string Name { get; set; }
    }

    interface ITest2
    {
        string Name { get; set; }
    }

    class TestClass : ITest1, ITest2
    {
        public string nameAlpha;
        public string nameBeta;
        string ITest1.Name { get; set; }

        string ITest2.Name { get; set; }

        public TestClass() { }

        public TestClass(string nameAlpha, string nameBeta)
        {
            ITest1 test1 = new TestClass();
            ITest2 test2 = new TestClass();
            test1.Name = nameAlpha;
            test2.Name = nameBeta;
            this.nameAlpha = test1.Name;
            this.nameBeta = test2.Name;
        }
    }

2.079 Beiträge seit 2012
vor einem Jahr

Ich fasse Mal zusammen:

Du hast eine Klasse mit einem Konstruktor mit zwei Name-Parametern
In diesem Konstruktor erzeugst Du zwei weitere Instanzen von dieser Klasse ohne Parameter
Diesen Instanzen (je Cast auf ITest1 und ITest2) setzt Du die Namen aus dem jeweiligen Parameter
Der aktuellen Instanz setzt Du die zwei neuen Instanz-Variablen nameAlpha und nameBeta (das sind keine Properties) anhand der zuvor gesetzten Name-Properties
Die zuvor erstellten Instanzen verwirfst Du ungenutzt
Die beiden Name-Properties der aktuellen Instanz bleiben leer

Klingt das sinnvoll? 😉
Für mich sieht das so aus, als versuchst Du Trial&Error irgendetwas zu erreichen, aber so funktioniert das nicht.
Du solltest dir entweder ein gutes Buch oder die Anleitungen von Microsoft dazu durchlesen, dann hast Du mehr Freude daran.

Ich vermute Mal, Du meinst folgendes:


class TestClass : ITest1, ITest2
{
    // DAS sind Properties - und halte dich an Namenskonventionen
    public string NameAlpha { get; set; }
    public string NameBeta { get; set; }

    string ITest1.Name
    {
        get { return NameAlpha; }
        set { NameAlpha = value; }
    }
    string ITest2.Name
    {
        get { return NameBeta; }
        set { NameBeta = value; }
    }

    public TestClass(string nameAlpha, string nameBeta)
    {
        NameAlpha = nameAlpha;
        NameBeta = nameBeta;
    }
}

S
sane Themenstarter:in
40 Beiträge seit 2022
vor einem Jahr

Danke dir!!

Warum einfach, wenns kompliziert auch geht!! Wenigstens kann kann ich über mich selber lachen.

Lg!

16.828 Beiträge seit 2008
vor einem Jahr

Ich schreibe meistens so:

War var früher mal eine gute Idee und hatte positive Effekte, wird var aufgrund des enormen Abuse-Potentials heute in vielen Bereichen - und dazu gehört dieser Fall definitiv - als Code Smell empfunden.
Von fehlender Barrierefreiheit mal abgesehen.

Gibt einfach kein Grund mehr für var.