Laden...

Generischer Methodenaufruf - Verständnisproblem

Erstellt von schoko01 vor 8 Jahren Letzter Beitrag vor 8 Jahren 983 Views
S
schoko01 Themenstarter:in
23 Beiträge seit 2006
vor 8 Jahren
Generischer Methodenaufruf - Verständnisproblem

Hallo @all

Ich habe eine FremdDll mit mehreren Klassen und Interfaces die alle die Methode GetFirstAttribute implementieren. (Alle haben jedoch kein gemeinsames Interface)

Vereinfachter Aufbau sieht ungefähr so aus ->


    interface IA
    {
        int GetFirstAttribute(out string pAttrName,  out object pAttrVal);
    }
    class A : IA
    {
        //........
        //Implementierung der Funktion
    }
    interface IB
    {
           int GetFirstAttribute(out string pAttrName,  out object pAttrVal);
    }
    class B : IB
    {
        //.......
        //Implementierung der Funktion
    }
    // Noch mehr Klassen mit GetFirstAttribute

    class Helper
    {
           public static Dictionary<string, object> GetAttibutes<TType>(TType Item)
               where TType : IA, IB
           {
               //.....
               string strAttrName;
               object objAttrValue;
               int iRetVal = Item.GetFirstAttribute(out strAttrName, out objAttrValue);
               //...
           }
    }

Rufe ich jetzt GetFirstAttribute in meiner generischen Methode GetAttributes auf bekomme ich folgende Fehlermeldung

Fehlermeldung:
Fehler 17 Der Aufruf unterscheidet nicht eindeutig zwischen folgenden Methoden und Eigenschaften: "Test.IA.GetFirstAttribute(out string, out object)" und "Test.IB.GetFirstAttribute(out string, out object)"

Ich dachte ja, dass der Compiler den Verweis auf die richtige Methode über TType bekommt.

Irgendwie stehe ich da auf der Leitung und hoffe auf Eure Hilfe.

Vielen Dank
lg Gerald

2.079 Beiträge seit 2012
vor 8 Jahren

Der Compiler kennt den Verweis nicht, der kennt nur die Definitionen.
Die Runtime kennt den Verweis, die entscheidet aber nicht, welche Methode aufgerufen wird.
Der Compiler bekommt den Verweis auf die Methode, da TType aber beide Interfaces implementieren muss, hat er zwei identische Methoden-Definitionen. Nun bleibt die Frage: Welche nimmt er?

Das kannst nur Du entscheiden und musst Du auch, indem Du vorher in eines der beiden Interfaces castest.

Alternativ kannst Du deine Methode überladen, einmal muss TType IA implementieren und einmal IB.
Dann weiß der Compiler, welche Methode aufgerufen werden soll.

Ich korrigiere: Die Methoden-Definition ist damit nicht unterschiedlich.

Du kommst also nicht um das Casten herum.
Ohne ein gemeinsames Interface gibt es keine schöne generische Lösung.

PS:
Oder Du machst die Methode nicht generisch und überladst sie dann mit dem Interface als Parameter-Typ:

public static Dictionary<string, object> GetAttibutes(IA Item)
{
}
public static Dictionary<string, object> GetAttibutes(IB Item)
{
}

NuGet Packages im Code auslesen
lock Alternative für async/await

Beim CleanCode zählen nicht die Regeln, sondern dass wir uns mit diesen Regeln befassen, selbst wenn wir sie nicht befolgen - hoffentlich nach reiflichen Überlegungen.

S
schoko01 Themenstarter:in
23 Beiträge seit 2006
vor 8 Jahren

Wow das ging ja schnell.

Ich hatte den Denkfehler also schon in der Einschränkung der generischen Methode (where TType : IA, IB)
Es werden ja von keiner Klasse beide Interfaces implementiert.

Vielen Dank für die schnelle Hilfe.

lg Gerald

PS.: Ich werde dann den Weg über das Überladen der Methoden gehen. 👍

2.298 Beiträge seit 2010
vor 8 Jahren

Hallo,

wieso steckst du die Schnittmenge der Interface-Methoden nicht noch einmal in ein übergeordnetes Interface?


interface IA
{
     int GetFirstAttribute(out string pAttrNam, out object pAttrVal);
}

interface IB : IA
{
    // weitere Methoden...
}

interface IC : IA
{
    // weitere Methoden...
}

class Helper
{
           public static Dictionary<string, object> GetAttibutes<TType>(TType Item) where TType : IA
           {
               //.....
               string strAttrName;
               object objAttrValue;
               int iRetVal = Item.GetFirstAttribute(out strAttrName, out objAttrValue);
               //...
           }
}

// Edit:
Gerade erst gelesen dass es eine fremd Assembly ist. Damit ist das wohl hinfällig.

Wissen ist nicht alles. Man muss es auch anwenden können.

PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager |