2012-03-25 6 views
6

Ich möchte nicht, dass meine Liste vom festen Typ ist. Ich möchte vielmehr, dass die Erstellung von List vom Typ der Variablen abhängig ist. Dieser Code funktioniert nicht:Wie erstelle ich einen dynamischen Typ Liste <T>

Kann mir jemand sagen, welche Änderungen ich vornehmen muss, damit es richtig funktioniert? Ich möchte, dass die Erstellung von list vom Typ der Variablen abhängig ist. something

+3

Sie müssen dafür Reflektion verwenden. Sie können statisch typisierte Variablen nicht verwenden. Oder finde einen anderen Ansatz. –

+1

Warum möchten Sie das tun? – svick

+0

"Ich möchte die Sicherheit, aber ich brauche dynamische Sicherheit." Können Sie das näher ausführen? –

Antwort

27
string something = "Apple"; 
Type type = something.GetType(); 
Type listType = typeof(List<>).MakeGenericType(new [] { type }); 
IList list = (IList)Activator.CreateInstance(listType); 

So erstellen Sie eine Liste statisch unbekannter Typen. Beachten Sie jedoch, dass Sie den Laufzeittyp der Liste nicht statisch angeben können. Sie müssen einen nicht generischen Typ oder ein Objekt verwenden.

Ohne mehr darüber zu wissen, was Sie erreichen möchten, ist dies das Beste, was Sie tun können.

+1

Cool! Außer ver brauchen var. – Jaggu

+2

@Jaggu Nein, 'var' wird nicht ganz das machen, was du denkst. Es wird Ihnen keine variable typisierte "Liste " geben, da 'var' ein statisches Typisierungskonstrukt ist. –

+0

Führt dies eine Überprüfung des Laufzeittyps auf Listenoperationen durch? Wenn Sie also versuchen, etwas hinzuzufügen, das nicht vom Typ "Apple" ist, tritt ein Laufzeitfehler auf? –

0

Der Compiler muss den generischen Typ T zur Kompilierzeit kennen. Also nein, das kannst du nicht wirklich tun.

5

Ich möchte Typ Sicherheit, aber ich brauche dynamische Art Sicherheit.

Wenn Sie meinen, Sie Laufzeittyp-Sicherheit wollen, können Sie List<T> erstellen mithilfe von Reflektion oder dynamic und dann behandeln sie als nicht-generic IList (usr Antwort sehen).

Mit dynamic, würde es in etwa so aussehen:

static List<T> CreateListByExample<T>(T obj) 
{ 
    return new List<T>(); 
} 

… 

object something = "Apple"; 

IList list = CreateListByExample((dynamic)something); 

list.Add(something); // OK 

list.Add(42);  // throws ArgumentException 
1

Die dynamische und Reflexion alle gut funktionieren - aber mit einem Nachteil auf die Leistung - und verlieren starke Typisierung, Code-Design/Klarheit usw.
also sollten Sie immer Dinge versuchen und zu lösen w/o es - wenn Sie können, Ihr Code ermöglicht es ...
So, und (Anmerkung) abhängig (sehr viel) auf Ihrem spezifischen Code, Bedürfnisse,
Sie könnten auch einen 'Trick' zu 'schließen' die Art verwenden und machen es generische ...

class Program 
{ 
    static void Main(string[] args) 
    { 
     string something = "Apple"; 
     int test = 5; 
     var list = something.GetList(); 
     var listint = test.GetList(); 
     Console.WriteLine(list.GetType()); 
    } 
} 
static class Extension 
{ 
    public static List<T> GetList<T>(this T value) 
    { 
     return new[] { value }.ToList(); 
    } 
} 

... d.h. Wenn Sie einen Wert für eine Variable haben und bevor Sie den generischen Kontext eingeben,
können Sie Erweiterungen verwenden (die sehr hilfreich dabei sind), und lassen Sie den Typ und einen List-Typ für Sie ableiten
HINWEIS: Dieses 'Umgehen' wird leider nicht immer ausgeführt und wenn Ihr Code 'zu dynamisch' ist (ich weiß, das ist nicht zu 'genau', aber außerhalb des Rahmens dafür) und wenn es von den reflektionsinduzierten Typen etc. abhängt.
dh es gibt keine saubere Lösung, dies ist nur ein Beispiel, Sie müssten etwas ins Schwitzen bringen :) um es für Sie arbeiten zu lassen - zB Sie können hier und da einen Wrapper-Typ benötigen, und offensichtlich ist das Erstellen einer Liste auf diese Weise möglicherweise nicht das, was Sie wollen usw.

Verwandte Themen