Laden...

Generische Eigenschaft erstellen, deren Typ erst zur Laufzeit bekannt wird

Erstellt von Nuramir vor 15 Jahren Letzter Beitrag vor 15 Jahren 1.628 Views
N
Nuramir Themenstarter:in
22 Beiträge seit 2008
vor 15 Jahren
Generische Eigenschaft erstellen, deren Typ erst zur Laufzeit bekannt wird

Hallo,

folgendes Problem stellt sich mir und die Suche hat mir dabei leider nicht wirklich geholfen. Ich benötige für eine Klasse eine generische Eigenschaft vom Typ List<T>, dabei wird der Typ in der Liste erst zur Laufzeit bekannt. Ich habe es mit folgendem probiert, doch dies führt nur zum Fehler das er T nicht kennt. Wie definiere ich denn nun eine Eigenschaft des Typs List<T>? Geht das überhaupt?


class MyClass
{
  public List<T> DataSource<T>
  {
    ...
  }
}

MyClass obj = new MyClass();
obj.DataSource = new List<irgendwas>();

946 Beiträge seit 2008
vor 15 Jahren

Den Typ kannst du mit dem typeof-Operator bestimmen.

Edit: Oder meinst du etwas anderes?

N
Nuramir Themenstarter:in
22 Beiträge seit 2008
vor 15 Jahren

Ich möchte gerne eine Eigenschaft generischen Typs erstellen. Mit typeof kann ich nur den Typ einer Klassendefinition laden.

Praktisch wie List<T> wobei T erst zur Laufzeit bekannt ist.

5.658 Beiträge seit 2006
vor 15 Jahren
class MyClass<T>
{
  public List<T> DataSource
  {
    ...
  }
}

MyClass<irgendwas> obj = new MyClass<irgendwas>();
obj.DataSource = new List<irgendwas>();

Weeks of programming can save you hours of planning

N
Nuramir Themenstarter:in
22 Beiträge seit 2008
vor 15 Jahren

Ich möchte eine generische Eigenschaft und keine generische Klasse definieren.

Dies ist nicht möglich da meine Klasse von einer nicht generischen Klasse erbt.

5.658 Beiträge seit 2006
vor 15 Jahren

anders geht es nicht.

// Edit:

Mit C# 4.0 geht folgendes:

class MyClass
{
  public List<object> DataSource
  {
    ...
  }
}

MyClass obj = new MyClass();
obj.DataSource = new List<irgendwas>();

Weeks of programming can save you hours of planning

49.485 Beiträge seit 2005
vor 15 Jahren

Hallo Nuramir,

Ich benötige für eine Klasse eine generische Eigenschaft vom Typ List<T>, dabei wird der Typ in der Liste erst zur Laufzeit bekannt.

das geht nicht. Die Typ-Parameter müssen zur Compilezeit bekannt sein.

herbivore

2.187 Beiträge seit 2005
vor 15 Jahren

Hallo Nuramir,

Das ganze ist nur über Reflection möglich und dadurch verlierst du wieder die Typensicherheit (der einzige Vorteil von Generics!).


public IList GetList(Type t)
{
  return (IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(T));
}

Es geht, ist aber nicht sonderlich sinn voll.

Gruß
Juy Juka

5.941 Beiträge seit 2005
vor 15 Jahren

Hallo JuyJuka

(der einzige Vorteil von Generics!).

Nö, ohne Generics gäbe es bspw. auch keine generischen Implementierungen.
D.h. pro Typ eine Klasse schreiben.

Es geht, ist aber nicht sonderlich sinn voll.

Also Reflection und auch Reflection mit Generics kann sinnvoll sein.
In deinem Beispiel sehe ich aber ehrlich gesagt gar kein Sinn.

Gruss Peter

--
Microsoft MVP - Visual Developer ASP / ASP.NET, Switzerland 2007 - 2011

N
Nuramir Themenstarter:in
22 Beiträge seit 2008
vor 15 Jahren

Hmm, irgendwie muss es gehen. Wie sonst kann es Methoden oder Eigenschaften von Komponenten geben die genau dieses machen? Leider habe ich den Source nicht zur Verfügung.

Bei den DevExpress.Xpo Komponenten z.B. gibt es generische Methoden ala

public object Evaluate<ClassType>(...)

Wenn ich das allerdings so deklariere ist ClassType unbekannt obwohl ich alles in uses deklariert habe was im Bsp. auch ist. Es ist auch unmöglich ClassType irgendwo zu finden. Wie machen die das? Vielleicht habe ich auch einfach nur etwas übersehen oder verstehe es falsch?

49.485 Beiträge seit 2005
vor 15 Jahren

Hallo Nuramir,

natürlich kann man public object Evaluate<ClassType>(...) schreiben. Und ClassType muss nirgendswo weiter auftauchen, weil das ja nur der Name für den Typ-Parameter ist (formaler Parameter). Ich meinte, dass du den Typ-Parameter selbst (also den aktuellen Parameter) zur Compilezeit angeben musst bzw. dass dieser zur Compilezeit bekannt sein muss. Und das ist notwendig. Ohne das funktionieren Generics nicht. Deshalb wirst du auch keinen Code finden, der so funktioniert, wie du willst. Die Typ-Parameter müssen zur Compilezeit bekannt sein.

Natürlich kann man per Reflection viel zur Laufzeit machen, auch im Zusammenhang mit Generics. Es gibt z.B. MethodBuilder.MakeGenericMethod und GenericTypeParameterBuilder.MakeGenericType. Aber dann musst du auch den Zugriff auf die Property über Reflection machen. Du wirst sie nicht normal benutzen können, wie das der Fall wäre, wenn der Typ-Parameter zur Compilezeit bekannt wäre.

herbivore