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
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.
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. 👍
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 |