| 

.NET C# Java Javascript Exception

2
Hallo zusammen...ich habe mich gefragt, ob es in C# die Möglichkeit gibt, bei der Definition von Klassen, den generischen Typparameter auf mehrere mögliche, unterschiedliche Typen einzuschränken ? Etwa in der Form:
class MyClass<T> where T:PossibleTypeOne, PossibleTypeTwo, PossibleTypeThree
? Also wäre für T der Typ
PossibleTypeOne
,
PossibleTypTwo
oder
PossibleTypeThree
...Würde mich freuen, wenn ihr hier für mich Licht ins Dunkel bringen könntet...Danke !
News:
30.03.2011
Gast
21 2
4 Antworten
2
Hi,
also
class Foo<T> where T : IBar, IBla, IBlub

funktioniert doch einwandfrei? Oder hab ich da gerade was falsch verstanden?
30.03.2011
Logdog82 856 1 8
Cool...Danke...ja...mit Interfaces funktioniert das Ganze wunderbar...aber nicht für Typen...man muss halt dann für jeden Typ ein eigenes Interface definieren...geht natürlich...ist aber schade, dass es nicht gleich für Typen geht...der Compiler könnte sich ja "hintendurch" automatisch ein Interface für jeden Typ definieren...was anderes machen ja Tools wie ReSharper beim Erzeugen von Interfaces aus Klassen auch nicht...schade..aber verschmerzbar.
– Gast 30.03.2011
Automatisch Interfaces durch den Compiler erzeugen wäre fatal. Woher soll der Compiler wissen welche Schnittstelle der Klasse nach aussen über ein Interface abgebildet werden soll ;-) Bei ReSharper kannst du noch im Nachhinein manuell Hand anlegen aber beim Compiler? ...
Wenns hilfreich war kannst du ja die Antwort als beantwortet markieren ;-)
Logdog82 30.03.2011
Seid Ihr Euch sicher, dass diese Konstruktion "oder"-Semantik hat? Ich würde eher "und"-Semantik erwarten, das heißt T muß alle 3 Interfaces implementieren. Analog zu einer Klassendefinition class T : IBar, IBla, IBlub.
Matthias Hlawatsch 30.03.2011
Ja so ist es auch. T muss all diese Interfaces implementieren. Das ist auch der Grund warum man keine Klassen angeben kann da keine Mehrfachvererbung in .NET möglich ist.
Logdog82 30.03.2011
Hallo zusammen...ich habe die Frage gestellt...in der Zwischenzeit bin ich als User registriert...leider kann ich die Frage nicht mehr als "beantwortet" markieren, da mein Browser in der Zwischenzeit "abgeschmiert" ist und ich die Frage nicht mehr editieren kann...soweit dazu...Nun zur Frage zurück: Es ist tatsächlich so, dass es sich um eine "UND-Verknüpfung" handelt, wie Matthias Hlawatsch geschrieben hat...T muss demnach ALLE angegebenen Interfaces implementieren, nicht eins davon.
gehaschu 30.03.2011
Noch ein Wort zum Erzeugen von Interfaces durch den Compiler:Der Compiler könnte alle "public" Methoden / Properties usw. als Interface extrahieren - macht ReSharper zunächst auch so, dann kann man aber noch einschränken. Zumindest wären dann alle "public" member des entsprechenden Typs verfügbar...ist aber natürlich nicht unbedingt immer angebracht.
gehaschu 30.03.2011
"kann ich die Frage nicht mehr als "beantwortet" markieren" hab ich mal gerade für dich erledigen lassen ;-)
Logdog82 30.03.2011
Schön...danke Dir Logdog82...damit ist die Diskussion dann dieser Frage dann wohl auch beendet.
gehaschu 30.03.2011
2
Wenn du allen möglichen Typen das selbe Interface zuweist, wäre das die einfachste Möglichkeit.
30.03.2011
Jürgen Gutsch 1,1k 4 7
Wow...das ging aber schnell..Danke für die Antwort...das Problem ist, dass die Typen in meinem konkreten Fall sehr unterschiedlich sind und ein gemeinsames Interface für diese Typen das Business Model verfälschen würde...dann prüfe ich lieber intern auf die zulässigen Typen...aber ich frage mich echt, ob es diese komfortable Möglichkeit in C# gibt bwz. wenn nicht, welche Gründe dagegen sprechen (aus architektonischer Hinsicht von Sprache bzw. Compiler).
– Gast 30.03.2011
2
Wenn die Typen so unterschiedlich sind, dass Du kein gemeinsames Interface dafür definieren kannst - wie willst Du dann in MyClass Code schreiben, der für alle möglichen Typen funktioniert? Falls Du an Casten gedacht hast - eines der Ziele von Typparametern ist ja gerade, typsicher ohne Casten codieren zu können.
Matthias Hlawatsch 30.03.2011
Es geht mir lediglich darum, dass ich nicht unbedingt ein "künstliches" Interface für unterschiedliche Typen definieren will, die eigentlich wenig miteinander zu tun haben und lediglich ein, zwei identische" Properties haben, nur um das "where" Konstrukt verwenden zu können.
Was es mir dann bringt ? Nun...der Compiler würde in dem Fall meckern, wenn ich die Klasse mit einem falschen Typ T instanziieren möchte und so wären die möglichen Typen von vorneherein zumindest eingeschränkt...geht ja aber in dem Fall nicht, weil es sich ja um eine "UND-Verknüpfung" handelt, wie Du gesagt hast.
gehaschu 30.03.2011
Wenn du das MarkerInterface entsprechent nennst, macht es wieder Sinn. Wie z. B. das Interface IRequireSessionState, dass für HttpHandler genutzt wird, die auf die Session zugreifen sollen.
Die Frage von Matthias, warum Du die verschiedenen Typen festlegen willst, die scheinbar keine Gemeinsamkeit haben, ist IMO berechtigt.
Kannst Du dennoch eine Gemeinsamkeit definieren, wäre das der Name für das MarkerInterface. Dann macht es nämlich durchaus Sinn ;-)
Jürgen Gutsch 30.03.2011
Es ist ja gerade der Witz von Interfaces, das sie es auszudrücken ermöglichen, dass eine bestimmte Funktionalität vorhanden ist ohne Rücksichtnahme darauf, was der Typ sonst noch kann. Schau Dir an, wieviele Klassen IDisposable implementieren - die haben ansonsten überhaupt nichts miteinander zu tun.

Ansonsten könnte es auch sein, dass ein Typparameter hier gar nicht die beste Lösung ist und Du mit einem überladenen Konstruktor oder überladenen Methoden besser fährst. Ich schreib gleich noch eine Antwort mit einem Beispiel.
Matthias Hlawatsch 30.03.2011
Da habt ihr natürlich Recht...ich denke momentan wohl zu stark im Business Model unserer Anwendung...und da gibt es einige Leute hier, die das strikt "überwachen", was die Definition neuer Interfaces usw. angeht ;-)
gehaschu 30.03.2011
0
das geht leider nicht was ich sehr schade finde. mehrere Typen sind nur dann erlaubt wenn die nächsten in der Reiche vom ersten Typen abgeleitet sind.
30.03.2011
pinchbeck 373 1 8
Danke für die Antwort...ja...geht leider für Typen nicht...aber wenigstens mit Interfaces, wie Logdog82 richtig geschrieben hat...
– Gast 30.03.2011
Achtung: Handelt sich aber - wie Matthias Hlawatsch geschrieben hat - um eine "UND", keine "ODER" Verknüpfung...T muss ALLE angegebenen Interfaces implementieren !
gehaschu 30.03.2011
0
Wenn Dir die Lösung mit dem gemeinsamen Interface nicht gefällt, könntest Du auch Überladung verwenden statt eines Typparameters. Nebeneffekt: die "gemeinsamen" Properties der einzelnen Typen, auf die Du zugreifen möchtest, müssen noch nicht mal gleich heißen. Nachteil: mehr Tipparbeit.

class MyClass
{
int relevantProp1;
string relevantProp2;

public MyClass(Typ1 typ1)
{
relevantProp1 = typ1.Prop1;
relevantProp2 = typ1.Prop2;
}

public MyClass(Typ2 typ2)
{
relevantProp1 = typ2.Prop1;
relevantProp2 = typ2.Prop2;
}

//...
}


oder

class MyClass
{
int relevantProp1;
string relevantProp2;

private void DoIt(int i, string s)
{
//...
}

public void DoIt(Typ1 typ1)
{
DoIt(typ1.Prop1, typ1.Prop2);
}

public void DoIt(Typ2 typ2)
{
DoIt(typ2.Prop1, typ2.Prop2);
}
}
30.03.2011
Matthias Hlawatsch 13,2k 4 9
Danke für die Anregung...ich habe es mittlerweile auch ähnlich implementiert...aber es ist immer schön zu sehen, wie es andere machen...man lernt ja nie aus. Nochmals Danke !
gehaschu 30.03.2011

Stelle deine .net-Frage jetzt!