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 #?

War es hilfreich?

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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top