2 Stimmen

Ein Objekt in eine Basissammlung umwandeln

Ich bin nicht ganz sicher, ob das möglich ist, aber ich versuche es. Ich habe eine Methode, die ein Objekt zurückgibt, obwohl der eigentliche Typ Collection ist. Nun kann ich das Objekt einfach in die Sammlung umwandeln, indem ich

var myCollection = myObject as Collection<MyClassA>;

Das Problem, das ich habe, ist jedoch, dass Collection<MyClassA> könnte alternativ sein Collection<MyClassB> o Collection<MyClassC> . Alle diese MyClassX werden geerbt von MyBaseClass Im Idealfall würde ich also gerne etwas wie folgt tun können

var myCollection = myObject as Collection<MyBaseClass>;

Dies führt jedoch beim Casting zu einer Ausnahme. Ist es möglich, dies in irgendeiner Weise zu tun? Ich verstehe, dass es innerhalb von .Net 4 sein kann?

Vielen Dank für die Hilfe.

EDIT: OK - Die bisherigen Antworten sind sehr nützlich, aber sie lösen nur den zweiten Teil der Lösung - Konvertierung/Casting von Sammlungen.

Ich bin mir immer noch nicht sicher, wie ich das Objekt zunächst in eine Sammlung umwandeln soll (ohne die Verwendung einer umfangreichen if-Anweisung für jeden der möglichen Typen)

2voto

Rex M Punkte 138455

Dies wird nur unterstützt mit IEnumerable<T> in .NET 4. Sehen Sie sich den Unterschied in den Signaturen an:

IEnumerable<T> :

public interface IEnumerable<out T> : IEnumerable

Collection<T> :

public class Collection<T> : IList<T>, 
ICollection<T>, IEnumerable<T>, IList, ICollection, IEnumerable

Das out Schlüsselwort im Typ-Parameter sagt .NET, dass es Varianz unterstützt.

1voto

code4life Punkte 15309

Alternative Lösung: Sie könnten Schnittstellen und Generika verwenden, um das zu erreichen, was Sie wollen.

public interface IMyClass
{
}

public class MyClassA : IMyClass
{
}

public class MyClassB : IMyClass
{
}

public class MyClassC : IMyClass
{
}

static void Main(string[] args)
{
    var listA = new List<IMyClass>{new MyClassA{}, new MyClassA{}};
    var listB = new List<IMyClass> { new MyClassB { }, new MyClassB { } };
    var listC = new List<IMyClass> { new MyClassC { }, new MyClassC { } };

    List<IMyClass> genericList = listA.Cast<IMyClass>().ToList();
}

So etwas lässt sich ordnungsgemäß kompilieren und ermöglicht es Ihnen außerdem, verschiedene Listen von Typen, die die gemeinsame Schnittstelle implementieren, derselben Variablen zuzuweisen (in diesem Fall genericList .

1voto

Nathan Anderson Punkte 6670

Bevor ich Zugang zu .NET 4 hatte, schrieb ich eine Erweiterungsmethode, die dies erreichte:

public static IEnumerable<U> CastCollection<T, U>(this IList<T> items) where U : class
{
   var collection = new List<U>();
   foreach (var item in items)
   {
      if (item is U)
      {
           var newItem = item as U;
           collection.Add(newItem);
      }
  }
  return collection;
}

Sie würden es so verwenden:

var myCollection = myObject.CastCollection<MyClassA, MyBaseClass>();

myCollection wird ein IEnumerable<MyBaseClass> in diesem Fall.

0voto

ventaur Punkte 1821

Dies ist nicht möglich, wenn die Sammlung als Ganzes gegossen wird. Sie können jedoch die einzelnen Elemente in eine neue Sammlung übertragen. Sehen Sie sich die Erweiterungsmethode Cast<> von LINQ an.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X