| 

.NET C# Java Javascript Exception

2
Was passiert wenn ich eine generische Funktion ohne Angabe des generischen Types verwende?

z.B.
Private Function setzeWertAuf1(of MyType)(ByVal lst as List(of MyType)) as List (of MyType)
For Each itm As MyType In lst
itm.Wert = 1
Next
Return lst
End Function


Der Aufruf wäre wie folgt:
lstNeu = setzWertAuf1(lstAlt)


Sollte der Compilier nicht warnen oder einen Fehler melden? Das die Signatur nicht stimmt?
News:
04.04.2011
schokostecker 108 5
Floyd 14,6k 3 9
Edit: Quellcode-Formatierung hinzugefügt (erhöht die Lesbarkeit deutlich ;))
Floyd 04.04.2011
4 Antworten
3
Wenn du einer generischen Methode MachWas(Of T)(liste As List(Of T)) beim Aufruf eine Liste eines beliebigen Typs übergibst, z.B.
Dim x as List(of Regenwurm)
MachWas(x)
dann erkennt der Compiler, dass der die Methode "MachWas(Of Regenwurm)" verwenden muss.
Du musst dies nur dann explizit durch eine zusätzliche Of-Angabe beim Aufruf festlegen, wenn der Typ aufgrund der Signatur nicht eindeutig bestimmt werden kann.
Beispiel:
Function GibWasZurück(Of T)(WasDenn as MöglichkeitenEnum) As List(Of T)
...
End Function

Dim l = GibWasZurück(Of Sonnenschirm)(MöglichkeitenEnum.Sonnenschirm)
04.04.2011
mahama 98 4
2
Solange lstNeu und lstAlt Listen des gleichen Typs sind, sehe ich keinen Grund für den Compiler bezüglich der Signatur etwas anzumerken.

Ich habe allerdings ein paar kleine Anmerkungen:
- Du implementierst eine Funktion, gibst aber nichts zurück (das sollte schon mal für eine Compiler-Warnung reichen). Eine Sub, die du mit "setzeWertAuf1(lst)" aufrufst, sollte genügen.
- Du willst innerhalb der generischen Funktion auf die Eigenschaft "Wert" zugreifen, obwohl du nicht weißt, ob der Typ des übergebenen Objekts eine solche Eigenschaft implementiert.

Wozu muss diese Funktion überhaupt generisch sein?
04.04.2011
mahama 98 4
0
Danke. Punkte 1: Fehlender Rückgabewert habe ich behoben. Hatte ich beim Übertragen vergessen. Sorry.

Das mit Wert1 stimmt. MyType hat eine "As ... IMyInterface" Einschränkung. Sprich ich weiß das Wert vorhanden ist.

Meine Frage ging in die Richtung:
1) lstNeu = setzWertAuf1(lstAlt)
2) lstNeu = setzWertAuf1(of List(of MyType as IMyInterface))(lstAlt)
sind diese beiden Aufrufe dür den Compiler gleich?

Die Funktion wollte ich generisch haben, da es derzeit zwei Interfaces sein können, mit denen die Funktion umgehen soll.
04.04.2011
schokostecker 108 5
zu 1)
lstNeu ist das gleiche Objekt wie lstAlt. Wozu die zweite ("neue") Liste? Der Funktionsaufruf gaukelt dem Aufrufer vor, dass die "alte" Liste bzw. deren Werte nicht verändert werden und dass die neu gesetzten Werte nur als "neue" Liste zurückgegeben werden. Dem ist aber nicht so.
mahama 04.04.2011
zu 2)
Wenn, dann würde die Zeile
lstNeu = setzWertAuf1(of KonkreterTyp)(lstAlt)
lauten, d.h.
- du brauchst kein "List(Of)", da du dies in der generischen Funktion ja schon drinstehen hast
- MyType verwirrt mich gerade. Ist das nun ein konkreter Typ (siehe deine Antwort) oder ist es der Platzhalter für einen beliebigen Typ (siehe deine ursprüngliche Frage). Ein beliebiger Typ wird bei Generics gerne mit "T" abgekürzt?
mahama 04.04.2011
0
Bitte nicht an dem Inhalt der Funktion aufhängen! Sondern am Aufruf :-)
Das die Funktionen derzeit mit Referenzen zu tun hat ist mir klar.

Meine Frage ist warum warnt der Compiler nicht beim Aufruf von 1).
Das ist für mich ein ungültiger Funktionsaufruf!

Denn es gibt nur EINE Funktion (jetzt Sub) mit der Signatur (generisch):
Private Sub setzeWertAuf1(of MyType)(ByVal lst as List(of MyType))
...
End Sub

Der Aufruf von 1) setzt eine Sub mit der Signatur (nicht generisch)
Private Sub setztWertAuf1(ByVal lst as List(of MyType))
voraus

Hinweis: MyType entspricht T
04.04.2011
schokostecker 108 5

Stelle deine .net-Frage jetzt!