2016-08-11 18 views
1

Ich versuche, einen Typ von einer Typ-Variable zu bekommen. Zum Beispiel:Holen Sie sich den tatsächlichen Typ von einem Typ Variable

Type t = typeof(String); 
var result = SomeGenericMethod<t>(); 

ist ein Fehler passiert, in der zweiten Zeile, weil t keine type ist, dann ist es eine Variable. Irgendeine Möglichkeit, es zu einem Typ zu machen?

+0

Warum können Sie nicht 'SomeGenericMethod ()' verwenden, wenn dies nicht Ihr Anwendungsfall ist, dann müssen Sie angeben, wie Sie es tatsächlich verwenden werden, da der beste Weg, es zu lösen, davon abhängt, wie Sie es tun. Angenommen, dass 'var' der Typ von' t' ist, dann ist das, was Sie wirklich wollen, 't result = ...' was ein ganz anderes Problem ist. –

+0

@ScottChamberlain, das scheint wie ein Beispiel ... um des Beispiels willen. Cyan, bitte geben Sie an, ob es ist oder nicht. – Mafii

+0

Ich bekomme den Typ als Parameter in einer Methode und dann möchte ich es an die generische Methode übergeben. Ja, es ist nur ein Beispiel. – Cyan

Antwort

4

Nein, Sie können den Wert eines Type Objekts zur Kompilierzeit nicht kennen, was Sie tun müssten, um ein Type Objekt als einen tatsächlichen Typ zu verwenden. Was auch immer Sie tun, dass Type verwenden muss, muss dies dynamisch tun, und nicht erfordern, dass ein Typ zur Kompilierzeit bekannt ist.

+1

Punkt ist, generische Typargumente müssen zur Kompilierzeit bekannt sein. +1 – Mafii

+1

Sie müssen zur Kompilierzeit bekannt sein, da sie Kompilierzeitschutz sind, nicht weil sie zum Kompilierungsprozess gehören. Generika, die beim Kompilieren überprüft werden, sind eine (lebensrettende) Sicherheitssache, keine reine Anforderung. – Max

7

Um eine Instanz einer generischen basiert auf einer Art zu machen, Sie Reflektion verwenden können, um eine Instanz der generischen mit dem Typ, den Sie verwenden möchten, bekommen, dann Activator verwenden diese Instanz zu erstellen:

Type t = typeof (string); //the type within our generic 

//the type of the generic, without type arguments 
Type listType = typeof (List<>); 

//the type of the generic with the type arguments added 
Type generictype = listType.MakeGenericType(t); 

//creates an instance of the generic with the type arguments. 
var x = Activator.CreateInstance(generictype); 

Beachten Sie, dass x hier eine object sein wird. Um Funktionen aufzurufen, z. B. .Sort(), müssen Sie eine dynamic machen.

Bitte beachten Sie, dass dieser Code schwer zu lesen, zu schreiben, zu pflegen, zu begründen, zu verstehen oder zu lieben ist. Wenn Sie irgendwelche Alternativen zur Notwendigkeit haben, diese Art von Struktur zu verwenden, erforschen Sie diese gründlich.

bearbeiten: Sie können auch das Objekt werfen Sie aus dem Activator, wie (IList)Activator.CreateInstance(genericType) erhalten. Dadurch erhalten Sie einige Funktionen, ohne auf Dynamik zurückgreifen zu müssen.

+0

Schön und falsch stehlen von [hier] (http://Stackoverflow.com/a/9860408/4558029) – lokusking

+0

@lokusking Ich bin mir nicht sicher, was Sie sagen wollen, obwohl ich bemerkt habe, dass Link über das Gießen der Objekt, das Sie von der Activator-Instanz erhalten haben. Ich werde meine Antwort diesbezüglich aktualisieren. – Max

+0

Es geht nicht darum, Instanzen zu erzeugen, sondern generische Methoden aufzurufen – lokusking

2

Eine hässliche Abhilfe mit Reflexion:

Klasse mit generischer Methode

public class Dummy { 
     public string WhatEver<T>() { 
      return "Hello"; 
     }  
    } 

Nutzungs

var d = new Dummy(); 
Type t = typeof(string); 
var result = typeof(Dummy).GetMethod("WhatEver").MakeGenericMethod(t).Invoke(d, null); 

Auf Klasse Instanziierung sieht Max-Lösung

Verwandte Themen