Gibt es einen „anonymen“ generic-Tag in C #, wie '?' in Java?
Frage
In Java kann man eine Variable von einem "unbekannten" generic Typ parametrisiert erklären, die wie folgt aussieht:
Foo<?> x;
Gibt es ein Äquivalent Konstrukt zu dieser Fragezeichen, in C #?
Lösung
Die kurze Antwort ist nein. Es gibt nicht eine gleichwertige Funktion in C #.
Eine Abhilfe, von C # aus Sicht der Java-Entwickler von Obasanjo Dare:
In bestimmten Fällen kann man ein Verfahren benötigen, die auf Datenstrukturen arbeiten, können jede Art enthalten, im Gegensatz zu denen, die eine bestimmte Art enthalten (zum Beispiel ein Verfahren, alle Objekte in einer Datenstruktur drucken), während nach wie vor unter Ausnutzung von die Vorteile der starken Typisierung in Generika. Der Mechanismus für die Angabe dieser in C # ist über eine Funktion generischer Typ Inferenz genannt, während in Java diese Wildcard-Typen erfolgt über. Die folgenden Codebeispiele zeigen, wie beiden Ansätze zum gleichen Ergebnis führen.
C # -Code
using System;
using System.Collections;
using System.Collections.Generic;
class Test{
//Prints the contents of any generic Stack by
//using generic type inference
public static void PrintStackContents<T>(Stack<T> s){
while(s.Count != 0){
Console.WriteLine(s.Pop());
}
}
public static void Main(String[] args){
Stack<int> s2 = new Stack<int>();
s2.Push(4);
s2.Push(5);
s2.Push(6);
PrintStackContents(s2);
Stack<string> s1 = new Stack<string>();
s1.Push("One");
s1.Push("Two");
s1.Push("Three");
PrintStackContents(s1);
}
}
Java-Code
import java.util.*;
class Test{
//Prints the contents of any generic Stack by
//specifying wildcard type
public static void PrintStackContents(Stack<?> s){
while(!s.empty()){
System.out.println(s.pop());
}
}
public static void main(String[] args){
Stack <Integer> s2 = new Stack <Integer>();
s2.push(4);
s2.push(5);
s2.push(6);
PrintStackContents(s2);
Stack<String> s1 = new Stack<String>();
s1.push("One");
s1.push("Two");
s1.push("Three");
PrintStackContents(s1);
}
}
Andere Tipps
AFAIK Sie, dass in C # nicht tun kann. Was die BCL tut und es gibt plenties von Beispielen gibt es eine Klasse zu erstellen, die nicht generisch ist und dann eine generische Klasse erstellen, die das Basisverhalten von dem vorherigen erbt. Siehe Beispiel unten.
class Foo
{
}
class Foo<T> : Foo
{
}
Das kann man so etwas schreiben:
Foo t = new Foo<int>();
Während zugegebenermaßen nicht der saubere Ansatz zu sein, Foo<object> x
Verwendung auch geeignet sein kann.
Es gibt nicht eine äquivalente Syntax in C #.
Es ist nicht (ganz) wahr, dass es kein Äquivalent in C # ist. Es gibt keine statische Äquivalent, die Sie als eine Art verwenden können, oder rufen Sie Methoden auf, das ist wahr. Dazu Antwort Jorges verwenden .
Auf der anderen Seite, manchmal braucht man die entsprechende Idee zum Nachdenken, und es gibt es eine äquivalent. Wenn Sie:
interface IFoo<T>
{
T Bar(T t, int n);
}
Sie können eine Type
erhalten, die IFoo<int>
mit typeof(IFoo<int>)
darstellt. Weniger bekannt, und eine teilweise Antwort auf Ihre Frage ist, dass Sie auch eine Type
die IFoo<T>
bekommen kann mit typeof(IFoo<>)
darstellt.
Dies ist nützlich, wenn Sie IFoo<T>
für einige T
durch Reflexion verwendet werden sollen und nicht T
erst zur Laufzeit kennen.
Type theInterface = typeof(IFoo<>);
Type theSpecificInterface = theInterface.MakeGenericType(typeof(string));
// theSpecificInterface now holds IFoo<string> even though we may not have known we wanted to use string until runtime
// proceed with reflection as normal, make late bound calls / constructions, emit DynamicMethod code, etc.
Nein, ist es nicht wirklich das gleiche Konzept in C #. Sie müßten auf eine Basisklasse von Foo (vielleicht ein nicht-generisch Foo), oder machen Sie die Methode, die Sie gerade arbeiten in generic selbst beziehen (so dass Sie Foo verweisen können, und lassen Sie den Anrufer Ihrer Methode bestimmen, was T ist).
Ich hoffe, das hilft.