2008-09-22 6 views

Antwort

26

Die kurze Antwort ist nein. Es gibt kein äquivalentes Feature in C#.

Umgehung des Problems von C# from a Java developer's perspective von Dare Obasanjo:

In bestimmten Fällen kann man braucht, ein Verfahren erstellen, die auf Datenstrukturen arbeiten, können jede Art im Gegensatz zu denjenigen enthalten, die eine bestimmte Art enthalten (beispielsweise ein Verfahren zur Drucken Sie alle Objekte in einer Datenstruktur aus und nutzen Sie gleichzeitig die Vorteile der starken Typisierung in Generika. Der Mechanismus für die Angabe in C# erfolgt über eine Funktion namens generische Typ-Inferenz, während dies in Java mit Wildcard-Typen geschieht. Die folgenden Codebeispiele zeigen, wie beide 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); 
    } 
} 
+1

Die C# -ähnliche Inferenz funktioniert auch in Java 6. Wird in Java dann noch verwendet? –

+21

Dies beantwortet nicht wirklich die Frage. Die Antwort ist nein". Der oben gezeigte Trick demonstriert eine Problemumgehung für die Capture-Konvertierung von Java in C#, die mit der Konvertierung von Methodenaufrufen funktioniert, aber nicht für die Umsetzungskonvertierung oder in einen Cast-Ausdruck nützlich ist. – Mishax

+4

In der Tat ist diese Antwort die längste Art zu sagen "Nein", die ich je gesehen habe :) – David

1

Nein, in C# gibt es nicht das gleiche Konzept. Sie müssten auf eine Basisklasse von Foo (vielleicht ein nicht-generisches Foo) verweisen oder die Methode, an der Sie arbeiten, selbst generisch machen (so dass Sie auf Foo verweisen können und den Aufrufer Ihrer Methode bestimmen lassen, was T ist ist).

Hoffe, dass hilft.

4

Es gibt keine entsprechende Syntax in C#.

12

AFAIK können Sie das nicht in C# tun. Was der BCL tut und es gibt viele Beispiele dafür, eine Klasse zu erstellen, die nicht generisch ist und dann eine generische Klasse zu erstellen, die das Basisverhalten von dem vorherigen übernimmt. Siehe Beispiel unten.

class Foo 
{ 
} 

class Foo<T> : Foo 
{ 
} 

Das kann man so etwas schreiben:

Foo t = new Foo<int>(); 
3

Es ist nicht (ganz) wahr, dass es kein Äquivalent in C# ist. Es gibt kein statisches Äquivalent, das Sie als Typ verwenden oder Methoden aufrufen können, wahr genug. Verwenden Sie dazu Jorge's answer.

Auf der anderen Seite, manchmal brauchen Sie die entsprechende Idee für die Reflexion, und es gibt ein Äquivalent dort. Wenn Sie:

interface IFoo<T> 
{ 
    T Bar(T t, int n); 
} 

können Sie ein 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 erhalten können, die IFoo<T> mit typeof(IFoo<>) darstellt.

Dies ist nützlich, wenn Sie IFoo<T> für einige T durch Reflexion verwenden möchten und T bis zur Laufzeit nicht wissen.

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

während sie zwar nicht die saubere Ansatz, auch Foo<object> x Verwendung geeignet sein.

+2

-1: mit 'object' wird der generische Typ auf alle Typen beschränkt, die die gemeinsame Superklasse' object' haben. –

+3

Funktioniert mit allem: Primitive, Klassenobjekte, Strukturen, Enums ... 'Liste list = new Liste (); list.Add (1); list.Add (neues DateTime()); list.Add (neues MyStruct()); list.Add (MyEnum.Enum1); ' – Dani

+0

Ich gebe zu, dass Sie Recht haben. –