Laden...

[erledigt] Rückgabewert bei LINQ-To-Objects-Abfrage

Erstellt von Elric vor 13 Jahren Letzter Beitrag vor 13 Jahren 2.926 Views
E
Elric Themenstarter:in
124 Beiträge seit 2006
vor 13 Jahren
[erledigt] Rückgabewert bei LINQ-To-Objects-Abfrage

Hallo Forum

Ich habe eine Frage zum Rückgabewert einer Linq-Abfrage (vlt. ist es auch ein Verständnisproblem, da ich mit Linq grad meine ersten Versuche mache):

Wenn man LINQ auf eine Menge (Collection) losläßt, ist der der Rückgabewert doch IEnumerable<T> bzw. IEnumerable<KeyValuePair<Tkey,Tvalue>>, wenn ich ein Dictionary habe.

LINQ ergibt ja eine Teilmenge der Ausgangsmenge, mit der man weiterarbeiten möchte und dazu wäre es natürlich super, wenn sie wieder vom gleichen Typ wäre (oder ist das so außergewöhnlich?). Also mein Problem:

Meine Menge ist vom Typ

Class Comments: Dictionary<String,String>

Nach der Linq-Abfrage ist die Menge aber vom Typ IEnumerable<KeyValuePair<String,String>>. Und ich sehe keine Möglichkeit (außer mit For elementeweise kopieren), wie ich wieder auf meine Comments-Klasse komme.

Danke im Voraus
elric

458 Beiträge seit 2007
vor 13 Jahren

Ist doch voellig Wurst, dass das ein IEnumerable<T> ist, da das Dictionary IEnumerbale implementiert.

Comments myNewDict = myOldDict.Where(LINQExpression);

funktioniert doch.

be the hammer, not the nail!

E
Elric Themenstarter:in
124 Beiträge seit 2006
vor 13 Jahren

also bei mir klappt das nicht. Da meckert der Compiler mit

Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string,string>>' to 'System.Collections.Generic.Dictionary<string,string>'.

(bzw. ".. to 'Comments'")

Und wenn ich noch vorher caste, dann kommt eben zur Laufzeit ein "unable to cast"-Fehler.

458 Beiträge seit 2007
vor 13 Jahren

Zeig doch mal die Comments-Klasse.
Isses gewollt dass die Klasse von Dictionary<string, string> ableitet und nicht einfach das IDictionary Interface implementiert?

be the hammer, not the nail!

S
902 Beiträge seit 2007
vor 13 Jahren

Hallo,

wie wäre es mit ToDictionary?

mfg
serial

E
Elric Themenstarter:in
124 Beiträge seit 2006
vor 13 Jahren

Zeig doch mal die Comments-Klasse.
Isses gewollt dass die Klasse von Dictionary<string, string> ableitet und nicht einfach das IDictionary Interface implementiert?

Ja, dass sie von Dictionary ableitet ist so gewollt, denn sie "ist ein" Dictionary mit ein paar Zusatzmethoden. Ich hab sie allerdings noch nicht implementiert, d.h. momentan sieht sie so aus:

	public class Comments:Dictionary<string,string>
	{
		public Comments()
		{	}
	}

Daran kanns also nicht liegen.

@serial: ToDictionary hab ich schon probiert, dann brauch ich aber einen Cast von Dictionary auf Comments, der auch nicht klappt.

S
417 Beiträge seit 2008
vor 13 Jahren

Hallo,

was genau möchtest du denn erreichen, ist mir nicht ganz klar.
Du hast eine Menge (IEnumerable<T>), in deinem Fall IEnumerable<KeyValuePair<TKey,TValue>>.
Wenn du darauf eine Abfrage loslässt, erhälst du natürlich die Elemente aus der Menge,
also wieder eine Untermenge vom Typ IEnumerable<KeyValuePair<TKey,TValue>>.
Wieso willst du das Ergebnis wieder zu deiner Comments Klasse casten?
Das versteh ich nicht so ganz.

S
902 Beiträge seit 2007
vor 13 Jahren

Hallo,

dann benutze doch einen Konstruktur, dem du die Elemente übergibst, und er daraus deine Klasse erstellt.

Eigene Umwandlungsoperatoren sind bei Schnittstellen und Basisklassen nicht erlaubt.

mfg
serial

1.044 Beiträge seit 2008
vor 13 Jahren

Hallo Elric,

das sind aber wirklich die Grundlagen. [Hinweis] Wie poste ich richtig? Punkt 1.1 und 1.1.1 und [Artikel] Delegaten, anonyme Methoden, Lambda-Ausdrücke & Co..

Wenn du dir nicht sicher bist, was als Typ zurückkommt, kannst du einfach var nehmen. Schau dir var dann im Debugger an oder verwende die GetType-Methode. Es kommt immer drauf an, ob die letze Methode dir z.B. eine_ IEnumerable<T>_ oder eine List<T> gibt.

zero_x

E
Elric Themenstarter:in
124 Beiträge seit 2006
vor 13 Jahren

Erstmal danke für die Antworten.

was genau möchtest du denn erreichen, ist mir nicht ganz klar.
Du hast eine Menge (IEnumerable<T>), in deinem Fall IEnumerable<KeyValuePair<TKey,TValue>>.
Wenn du darauf eine Abfrage loslässt, erhälst du natürlich die Elemente aus der Menge,
also wieder eine Untermenge vom Typ IEnumerable<KeyValuePair<TKey,TValue>>.
Wieso willst du das Ergebnis wieder zu deiner Comments Klasse casten?
Das versteh ich nicht so ganz.

Meine Ausgangsmenge ist vom Typ Comments, also ein Dictionary mit Zusatzmethoden, vorstellbar wäre ein "SpeichereDich()", nur um ein Beispiel zu machen. Jetzt will ich die Menge (mit Linq) einschränken und diese Teilmenge "abspeichern". Dazu muss der Rückgabewert natürlich wieder vom Typ Comments sein.

dann benutze doch einen Konstruktur, dem du die Elemente übergibst, und er daraus deine Klasse erstellt.

Hab ich auch schon gemacht, aber dann muss ich, wie gesagt, elementeweise umkopieren. Mach ich dann auch, aber ich hätte eben erwartet, dass es einfacher geht.

@zero_x
Ich hätte jetzt nicht gesagt, dass es da an Grundlagen fehlt. Ich hab meine Collections richtig erstellt und auch mit Linq/Lambda-Ausdrücken das Ergebnis richtig rausbekommen. Nur mit dem Typ der Rückgabe bin ich nicht zufrieden. Oder anders gesagt, ich kann irgendwie kann nicht glauben, dass mein Anliegen, den gleichen Typ wieder rauszubekommen so, ungewöhnlich ist.

Ist doch nichts anderes wie ein "Select * .. where" auf eine Datenbanktabelle. Da erwarte ich auch die gleichen Spalten wie in der Tabelle, damit ich gut weiterarbeiten kann.

6.911 Beiträge seit 2009
vor 13 Jahren

Hallo,

Ist doch nichts anderes wie ein "Select * .. where" auf eine Datenbanktabelle. Da erwarte ich auch die gleichen Spalten wie in der Tabelle

vllt. liegt da dein Verständnisproblem. Bei SQL bekommst du als Ergebnis eine Menge wo der Typ der Spalten erhalten bleibt und nicht den Typ der Tabelle.

Bei LINQ wenn du zB als Quelle eine List<int> hast dann bleibt der Typ int auch erhalten, aber nicht das List<T> denn das Ergebnis liegt nun mal als IEnumerable<int> vor. Um davon wieder eine List<int> zu erhalten muss eine neue Liste erstellt werden, entweder mit new List<int>(myQuery) oder mit myQuery.ToList() wobei myQuery das IEnumerable<int> von LINQ ist.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

E
Elric Themenstarter:in
124 Beiträge seit 2006
vor 13 Jahren

Danke Dir, gfoidl. Ja, ich denke Du hast es richtig getroffen. An der Stelle hats gefehlt und jetzt dämmerts langsam. 😉

Und nun ist auch klar, dass das nicht gehen kann, was ich meinte. Das gewünschte Ergebnis bekomme ich trotzdem relativ einfach wie Du schreibst (bzw. hat es 'serial' weiter oben schon genauso geschrieben, nur hab ichs da noch nicht kapiert)

Ich hab jetzt der Comments-Klasse einen weiteren Konstruktor gegeben:

public Comments(Dictionary<string, string> dic): base(dic) {}

Zusammen mit der ToDictionary-Methode an der Query bin ich dann auch schon fertig.

Ja, wieder was gelernt. Nochmal Danke an alle.