Laden...

Unterschiedlichen Typen in List<Interface> finden

Erstellt von Curse4Life vor 12 Jahren Letzter Beitrag vor 12 Jahren 3.958 Views
C
Curse4Life Themenstarter:in
452 Beiträge seit 2005
vor 12 Jahren
Unterschiedlichen Typen in List<Interface> finden

Hallo,

ich habe eine kleine Frage.
Ich habe eine Liste vom Typ List<ITest> und zwei Typen (a und b) die dieses Interface implementieren.

Nun mache ich:


List<ITest> liste = new List<ITest>();

liste.Add(new a());
liste.Add(new a());
liste.Add(new b());
liste.Add(new a());
liste.Add(new b());
liste.Add(new b());

Es können aber unendlich viele Typen werden die ich nicht kenne die in die Liste gespeichern werden.

Nun möchte ich zwei Schritte machen.

  1. Ich möchte gerne die unterschiedlichen Typen in der Liste finden.
    In dem Beispiel a und b.

  2. Möchte ich gerne für jeden Typen aus Schritt 1 durch die Liste gehen und dann nur die Einträge des übergebenen Typen berücksichtigen.
    Also sprachlich ausgedrückt.

Ich habe mir jetzt im ersten Schritt die unterschiedlichen Typen geholt und jetzt rufe ich CompareEntries(List<ITest> liste, Type type) mit der vollen Liste und erst a und dann b als type auf.
Natürlich dynamisch.

Kann mir jemand dabei helfen?

643 Beiträge seit 2006
vor 12 Jahren

ich würde einefach die liste mit einer schleife interieren und dan

if (listItem is A)
... listItem.DoSomething();

C
Curse4Life Themenstarter:in
452 Beiträge seit 2005
vor 12 Jahren

Das geht aus mehreren Gründen nicht, ich kenne A z.B. überhaupt nicht, ich kenne nicht die Typen die ITest implementieren, dass muss schon alles dynamisch sein.

4.939 Beiträge seit 2008
vor 12 Jahren

Hallo,

dann würde ich vorschlagen, du iterierst die Liste und legst für jeden Typ eine Liste innerhalb eines Dictionary an, d.h:


Dictionary<Type, List<ITest>> dict;

foreach(ITest item in liste)
{
  Type type = item.GetType();

  if(!dict.Contains(type))
    dict[type] = new List<ITest>();

  dict[type].Add(item);
}

Aber warum willst du überhaupt die eigentlichen Typen unterscheiden? Interfaces dienen ja gerade dazu, daß man eben nur die gemeinsamen Methoden/Eigenschaften benutzt (ohne den konkreten Typ zu kennen).

C
Curse4Life Themenstarter:in
452 Beiträge seit 2005
vor 12 Jahren

Das kann ich ganz einfach erklären, das Interface (Und damit natürlich auch jeder Typ der dieses Implementiert) hat zwei Methode GetMinVersion() und GetMaxVersion().

Und ich muss jetzt jeweils für jeden Typ den größten gemeinsamen Nenner finden.

Also wenn Typ a 3x drin ist:

a(minVersion = "1.3.0"; maxVersion = "1.5.0")
a(minVersion = "1.3.0"; maxVersion = "1.4.0")
a(minVersion = "1.4.0"; maxVersion = "1.6.0")

wäre der gemeinsame Nenner "1.4.0", aber diesen muss ich eben pro Typ rausfinden und nicht global für alle Typen.

Und um diesen zu finden muss ich alle Einträge zu diesem Typen mit einander vergleichen.

1.029 Beiträge seit 2010
vor 12 Jahren

Hallo,

spricht hier etwas dagegen?:

namespace ConsoleApplication2
{
	class Program
	{
		static void Main(string[] args)
		{
			List<ITest> list = new List<ITest>();
			list.Add(new A() { Min = 1, Max = 2 });
			list.Add(new A() { Min = 0, Max = 3 });
			list.Add(new B() { Min = 5, Max = 20 });
			list.Add(new B() { Min = 3, Max = 50 });
                                                  // relevanter code:
			foreach (Type t in list.Select(item => item.GetType()).Distinct())
				Console.WriteLine("Version for Type {0} is {1}", t.Name, CheckVersions(list.Where(item => item.GetType() == t)));
                                                  // irrelevant
			Console.ReadLine();
		}

		static int CheckVersions(IEnumerable<ITest> test)
		{
			// check versions, etc...
			return 0;
		}
	}

	public interface ITest
	{
		int Min { get; set; }
		int Max { get; set; }
	}

	public class A : ITest
	{
		public int Min { get; set; }
		public int Max { get; set; }
	}

	public class B : ITest
	{
		public int Min { get; set; }
		public int Max { get; set; }
	}
}

Damit hat man recht einfach eine/mehrere Listen bzw. IEnumerables für jeden unterschiedlichen Typ.

LG
Achim

C
Curse4Life Themenstarter:in
452 Beiträge seit 2005
vor 12 Jahren

Nein, das sieht erst mal sehr gut aus, werds gleich mal testen, aber schon mal danke!

W
872 Beiträge seit 2005
vor 12 Jahren

List<ITest> liste = new List<ITest>();
Dictionary<Type, double> Max = new Dictionary<Type, double>();
Dictionary<Type, double> Min = new Dictionary<Type, double>();

foreach(ITest item in liste)
{
  Type type = item.GetType();
  if (!Max.Contains(type))
    Max.Add(type, item.maxVersion);
  if (!Min.Contains(type))
    Min.Add(type, item.minVersion);
  if (Min[type]>item.minVersion)
Min[type]=item.minVersion;
  if (Max[type]>item.maxVersion)
Max[type]=item.maxVersion;

}

S
417 Beiträge seit 2008
vor 12 Jahren

Hallo,

du brauchst einfach nur groupieren und das Minimum finden.
Um das Beispiel von Taipi88 aufzugreifen:

static void Main(string[] args)
{
	var list = new List<ITest>();
	list.Add(new A() { Min = 1, Max = 2 });
	list.Add(new A() { Min = 0, Max = 3 });
	list.Add(new B() { Min = 5, Max = 20 });
	list.Add(new B() { Min = 3, Max = 50 });

	var dict = list.GroupBy(f => f.GetType()).ToDictionary(k => k.Key, v => v.Min(x => x.Max));
	// dict[typeof(A)] == 2
	// dict[typeof(B)] == 20
}

Damit erhälst du ein Dictionary<Type,int> mit den Typen und der jeweiligen Version.