public interface InterfaceOfAType { }
public class AType : InterfaceOfAType { }
public InterfaceOfAType getInstanceOfAType()
{ return new AType(); }
public List<T> genericFunction<T>() where T : InterfaceOfAType
{
List<InterfaceOfAType> instance = new List<InterfaceOfAType>();
instance.Add(getInstanceOfAType());
instance.Add(getInstanceOfAType());
instance.Add(getInstanceOfAType());
// return a listcopy of instance
List<T> t = new List<T>();
t.AddRange(instance); // !! Fehler
return t;
}Die beste Übereinstimmung für die überladene List<T>.AddRange(IEnumerable<T>)-Methode hat einige ungültige Argumente.
|
News:
|
|
Edit: C#-Tagg hinzugefügt
– Floyd 05.04.2011
|
public List<InterfaceOfAType> NonGenericFunction()
{
List<InterfaceOfAType> instance = new List<InterfaceOfAType>();
instance.Add(getInstanceOfAType());
instance.Add(getInstanceOfAType());
instance.Add(getInstanceOfAType());
// return a listcopy of instance
List<InterfaceOfAType> t = new List<InterfaceOfAType>();
t.AddRange(instance);// !! kein Fehler mehr
return t;
}
public interface InterfaceOfAType { void Foo();}
public interface ExtendedInterfaceOfAType : InterfaceOfAType { void Foo2(); }
public class AType : ExtendedInterfaceOfAType
{
public void Foo() { }
public void Foo2() { }
}
public ExtendedInterfaceOfAType getInstanceOfAType()
{ return new AType(); }
public List<InterfaceOfAType> NonGenericFunction()
{
List<InterfaceOfAType> instance = new List<InterfaceOfAType>();
instance.Add(getInstanceOfAType());
instance.Add(getInstanceOfAType());
instance.Add(getInstanceOfAType());
// return a listcopy of instance
List<InterfaceOfAType> t = new List<InterfaceOfAType>();
t.AddRange(instance);// !! kein Fehler mehr
return t;
}foreach (ExtendedInterfaceOfAType interfaceOfAType in NonGenericFunction())
{
interfaceOfAType.Foo();
interfaceOfAType.Foo2();
}
|
|
|
Grund ist, das InterfaceOfAType nur eine Basis Interface sein soll, und ein interface ExtendedInterfaceOfAType ebenfalls bearbeitet werden sollte. Ich glaube ich erhoffe mir zu viel von Generics. :-)
– smartic 05.04.2011
|
||
|
Dein Code erzeugt eine Liste von AType-Instanzen. AType implementiert nicht ExtendedInterfaceOfAType, oder? Und auch allgemein gilt: nicht jede Instanz von InterfaceOfAType ist auch eine Instanz von ExtendedInterfaceOfAType. genericFunction<ExtendedInterfaceOfAType> müßte aber genau das liefern: eine Liste von Instanzen einer Klasse, die ExtendedInterfaceOfAType implementiert. Die muss irgendwo herkommen, und das "woher" ist die Frage, die Du beantworten musst. Wenn das geklärt ist, könntest Du z.B. getInstanceOfAType umbauen zu getInstance<T> - und dann passt das auch wieder zusammen.
– Matthias Hlawatsch 05.04.2011
|
||
|
So, nun denke ich mal dass was ich vorhatte so nicht gehen kann, obwohl die erste Implementierung funktioniert, aber in Blick auf die Erweiterung fehl schlagen muss. Ich werde wohl das Konzept mit der NonGenericFunction umsetzen, da dies plausibel klingt. Danke für den Hinweis.
– smartic 05.04.2011
|
class OtherType : InterfaceOfATypeeinführt und dann genericFunction<OtherType>() aufruft. Eine List<OtherType> kannst Du mit den Elementen von instance aber nicht herbeizaubern, denn da stecken AType-Instanzen drin, und die haben mit OtherType nichts zu tun.
|
|
// return a listcopy of instance
List<T> t = new List<T>();
t.AddRange(instance.Cast<T>());
return t;
|
|
|
-1: Das kompiliert, liefert aber u.U. zur Laufzeit eine InvalidCastException - nämlich dann, wenn irgendjemand class OtherType : InterfaceOfAType einführt und dann jemand genericFunction<OtherType> aufruft.
– Matthias Hlawatsch 05.04.2011
|
||
|
gilt dies auch für eine Konvertierung wie?
List<T> ts = new List<T>(); foreach (T t in instance) ts.Add((T)t); Ich verwende mom. noch .net.2.0 – smartic 05.04.2011
|
||
|
@smartic: warum die foreach-Zeile überhaupt kompiliert, verstehe ich ehrlich gesagt gerade nicht. In instance ist nicht "T", sondern (irgendein) InterfaceOfAType. - Ansonsten läuft es aber trotzdem darauf hinaus, AType in OtherType zu casten, und das wird nicht gehen.
– Matthias Hlawatsch 05.04.2011
|
||
|
mhh, eigentlich enthält die Liste nur das Interface vom Typ InterfaceOfAType, also "Cast"e/stecke ich nur das Interface von AType in die liste. Den Generic grenze ich ja ein, indem ich sage das er nur von einem bestimmten Interface sein darf. Wenn ich die Listen-Members verwende, verwende ich ebenso auch nur das Interface. Ein Objekt-Type-Cast findet nach meinem Verständnis nicht statt.
– smartic 05.04.2011
|
||
|
Du grenzt den Typparameter dahingehend ein, dass nur Typen erlaubt sind, die das Interface implementieren. D.h. man darf genericFunction für jedes T aufrufen, das das Interface implementiert, und dann erwarten, dass eine Liste von Ts zurückkommt - und nicht eine Liste von Instanzen irgendeines (anderen) Typs, der auch das Interface implementiert - in Deinem Fall AType. Durchdenke Dir nochmal den Fall mit OtherType: genericFunction<OtherType> muss eine List<OtherType> zurückgeben, aber instance enthält nichts vom Typ OtherType.
– Matthias Hlawatsch 05.04.2011
|