2017-12-05 4 views
1

ich eine Reihe von Klassen, die von EF erzeugt haben, die einfache Tabellen und haben ähnliche Strukturen:Objekt vom Typ erstellen in einem String angegeben

public class Contact 
{ 
    public int ID { get; set; } 
    public string Description { get; set; } 
} 

public class Member 
{ 
    public int ID { get; set; } 
    public string Description { get; set; } 
} 

Ich habe auch ein Verfahren für die Rückgabe eines Objekts eines bestimmten bekam Typ:

public T GetInstance<T>(string type) 
{ 
    return (T)Activator.CreateInstance(Type.GetType(type)); 
} 

Was ich will, ist, etwas zu tun wie folgt aus:

public ActionResult GetAll(string ClassType)  // ClassType will be the name of one of the classes above 
{ 
    Object LookupType = GetInstance<Object>(ClassType); 

    List<LookupType> AllList = new List<LookupType>(); 

    AllList = repo.GetAll<LookupType>().ToList<LookupType>(); // some generic method that will return a list; 
} 

Dies macht die Compiler verrückt, weil ich eine Variable (LookupType) anstelle eines echten Typs zum Erstellen der Liste verwenden. Beide funktionieren jedoch auch nicht:

Beide verursachen einen Fehler - "Verwenden generischer Typ Liste erfordert 1 Typ Argument".

Gibt es einen geeigneten Weg, dies zu tun? Gibt es eine Möglichkeit, ClassType direkt in einen Typ zu konvertieren, ohne es zu einem Objekt zu machen (von dem ich hoffe, den Typ abzuleiten)?

Antwort

2

Versuchen Sie, die CreateInstance Methode

SomeObject someObject = new SomeObject(); 
Type type = someObject.GetType(); 

Type listType = typeof(List<>).MakeGenericType(new [] { type }); 
IList list = (IList)Activator.CreateInstance(listType); 
+0

Dank - IList wird es nicht schneiden, weil es nicht in EF Lambda-Abfragen verwenden kann. – BKahuna

0

Sie können nicht tun es mit C# !! Compiler muss den Parametertyp kennen. Indem vielleicht möchten Sie erreichen möchten, Schnittstellen Ihnen helfen

public class Contact: IIdDescription 
{ 
     public int ID { get; set; } 
     public string Description { get; set; } 
} 

public class Member: IIdDescription 
{ 
    public int ID { get; set; } 
    public string Description { get; set; } 
} 

public interface IIdDescription 
{ 
    int ID { get; set; } 
    string Description { get; set; } 
} 



public ActionResult GetAll(string type)   
{ 
    var AllList = new List<IIdDescription>(); 

    if(type == Member.GetType().Name) 
     AllList = repo.Set<Member>().Cast<IIdDescription >().ToList(); 
    if(type == Contact.GetType().Name) 
     AllList = repo.Set<Contact>().Cast<IIdDescription >().ToList(); 

    ... 
} 

und in Ihre Ansicht Benutzeroberfläche als Modell, so etwas wie

@model IEnumerable<IIdDescription> 
+0

Eine Case-Anweisung (oder mehrere If-Then) ist genau das, was ich versuche zu vermeiden. – BKahuna

+0

in Ihrem Repo DbContext sollten Sie ein Dictionary > wo TEntity: Klasse und verwenden Sie als AllList = Repo.MyDict [Typ] .ToList(). Cast () – Ozzy

0

Wenn Sie die Art vor der Zeit nicht wissen, Vielleicht hilft eine Liste dynamischer Objekte.

var item = GetInstance<Contact>("Namespace.Contact"); 
    var items = new List<dynamic>(); 

    items.Add(item); 

Sie können dann die Typen zugreifen wie so ...

Contact contact = items[0]; 

Seien Sie sich bewusst sein, dass die dynamische Verwendung kann teuer werden.

Verwandte Themen