Das Folgende ist ein Auszug aus meinem Code:
public class AllIntegerIDs
{
public AllIntegerIDs()
{
m_MessageID = 0;
m_MessageType = 0;
m_ClassID = 0;
m_CategoryID = 0;
m_MessageText = null;
}
~AllIntegerIDs()
{
}
public void SetIntegerValues (int messageID, int messagetype,
int classID, int categoryID)
{
this.m_MessageID = messageID;
this.m_MessageType = messagetype;
this.m_ClassID = classID;
this.m_CategoryID = categoryID;
}
public string m_MessageText;
public int m_MessageID;
public int m_MessageType;
public int m_ClassID;
public int m_CategoryID;
}
Ich versuche, in meinem main () - Funktionscode Folgendes zu verwenden:
List<AllIntegerIDs> integerList = new List<AllIntegerIDs>();
/* some code here that is ised for following assignments*/
{
integerList.Add(new AllIntegerIDs());
index++;
integerList[index].m_MessageID = (int)IntegerIDsSubstring[IntOffset];
integerList[index].m_MessageType = (int)IntegerIDsSubstring[IntOffset + 1];
integerList[index].m_ClassID = (int)IntegerIDsSubstring[IntOffset + 2];
integerList[index].m_CategoryID = (int)IntegerIDsSubstring[IntOffset + 3];
integerList[index].m_MessageText = MessageTextSubstring;
}
Das Problem ist hier: Ich versuche, alle Elemente in meiner Liste mit einer for-Schleife zu drucken:
for (int cnt3 = 0 ; cnt3 <= integerList.FindLastIndex ; cnt3++) //<----PROBLEM HERE
{
Console.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}\n", integerList[cnt3].m_MessageID,integerList[cnt3].m_MessageType,integerList[cnt3].m_ClassID,integerList[cnt3].m_CategoryID, integerList[cnt3].m_MessageText);
}
Ich möchte das letzte Element finden, damit ich cnt3 in meiner for-Schleife gleichsetze und alle Einträge in der Liste ausdrucke. Jedes Element in der Liste ist ein Objekt der Klasse AllIntegerIDs, wie oben im Codebeispiel erwähnt. Wie finde ich den letzten gültigen Eintrag in der Liste?
Sollte ich so etwas wie integerList.Find (integerList []. M_MessageText == null;
Wenn ich das benutze, braucht es einen Index, der von 0 bis zu jedem Maximum reicht. Das heißt, ich muss eine andere for-Schleife verwenden, die ich nicht verwenden möchte. Gibt es einen kürzeren / besseren Weg?
Danke, Viren
AllIntegerIDs newItem = new AllIntegerID();
, alle Felder zuzuweisen und dann aufzurufenintegerList.Add(newItem)
. Oder verwenden Sie Eigenschaften anstelle von Feldern und verwenden Sie die C # 3.0-Objektinitialisierersyntax.Antworten:
Wenn Sie nur auf das letzte Element in der Liste zugreifen möchten, können Sie dies tun
Um die Gesamtzahl der Elemente in der Liste abzurufen, können Sie die Count-Eigenschaft verwenden
quelle
Last
/LastOrDefault
wie unten erwähnt zu verwenden.Enumerable.Last
löst eine Ausnahme aus, wenn die Liste leer ist. Wenn SieEnumerable.LastOrDefault
eine Liste von Werttypen aufrufen und übergeben, wird der Standardwert zurückgegeben, wenn die Liste leer ist. Wenn Sie also 0 von a zurückerhalten,List<int>
wissen Sie nicht, ob die Liste leer oder der letzte Wert 0 war. Kurz gesagt, Sie müssen denCount
Abrufmechanismus überprüfen, den Sie verwenden möchten.var element = list[list.Count - 1]
ist, halte ich sie für sehr prägnant und lesbar. Keine Notwendigkeit, ErweiterungsmethodenVerwenden Sie die Erweiterungsmethoden LastOrDefault () und Last (), um das letzte Element einer Sammlung abzurufen
ODER
Denken Sie daran, hinzuzufügen
using System.Linq;
, oder diese Methode ist nicht verfügbar.quelle
First
,FirstOrDefault
,Last
,LastOrDefault
,Single
,SingleOrDefault
,ElementAt
undElementAtOrDefault
sind optimiert fürIList<TSource>
,Count
undContains
sind für eine optimierteICollection<TSource>
undCast<TResult>
ist optimiert fürIEnumerable<TResult>
.using System.Linq;
System.Linq.Enumerable
sind nicht wirklich "optimiert". Hier ist der Code für dieEnumerable.Last
Methode.System.Linq.Enumerable.Last
stimme ich 0b101010 zu - derLast()
Code ist nicht "fürList<>
s optimiert " -Last()
ist nur ein hässlicher Wrapper, der standardmäßig verwendet wird,return list[list.Count-1]
falls das Argument ein istIList
, und die Liste bis zum Ende durchläuft, falls Es ist nicht ... eine sehr schlechte Lösung, wennIList
es sich um eine handeltLinkedList
, da der Indexer nur unnötig die gesamte Liste durchläuft (ich habe keine Überschreibung gefunden, dieItem[]
mit index> Count / 2 in den c # -Quellen, YMMV, rückwärts iteriert )Gehen wir der Frage auf den Grund, wie das letzte Element einer Liste sicher angesprochen werden kann ...
Vorausgesetzt
Dann
"count-1" ist eine schlechte Angewohnheit, es sei denn, Sie garantieren zuerst, dass die Liste nicht leer ist.
Es gibt keine bequeme Möglichkeit, nach der leeren Liste zu suchen, außer dies zu tun.
Der kürzeste Weg, den ich mir vorstellen kann, ist
Sie können alles daran setzen, einen Delegaten zu erstellen, der immer true zurückgibt, und ihn an FindLast übergeben, der den letzten Wert zurückgibt (oder standardmäßig einen Wert, wenn die Liste leer ist). Diese Funktion beginnt am Ende der Liste, ist also Big O (1) oder konstante Zeit, obwohl die Methode normalerweise O (n) ist.
Die FindLast-Methode ist hässlich, wenn Sie den Delegatenteil zählen, sie muss jedoch nur an einer Stelle deklariert werden. Wenn die Liste leer ist, wird ein standardmäßig erstellter Wert vom Listentyp "" für Zeichenfolge zurückgegeben. Es wäre nützlicher, den delegierten alwaysTrue-Schritt weiter zu gehen und ihn anstelle des Zeichenfolgentyps zu einer Vorlage zu machen.
quelle
myList.FindLast(_unused_variable_name => true);
Dies funktioniert unabhängig vom Typ. Eine kürzere Version istmyList.FindLast(_ => true);
, aber ich finde, dass nur der Unterstrich (oder eine andere Einzelzeichen-ID) manchmal etwas verwirrend sein kann.quelle
Veränderung
zu
quelle
Verwenden Sie die
Count
Eigenschaft. Der letzte Index wird seinCount - 1
.quelle
Sie finden es, indem Sie zuerst die Anzahl der Elemente in der Liste zählen, z
Dann können Sie die Anzahl 1 indizieren, um das letzte Element in der Liste zu erhalten, z
quelle
In C # 8.0 erhalten Sie das letzte Element mit der vollständigen Erklärung des Operators ^
quelle
Warum nicht einfach die Count-Eigenschaft in der Liste verwenden?
quelle
Unabhängig von Ihrer ursprünglichen Frage erzielen Sie eine bessere Leistung, wenn Sie Verweise auf lokale Variablen erfassen, anstatt sie mehrmals in Ihre Liste zu indizieren:
Und in Ihrer
for
Schleife:quelle
Ich müsste zustimmen, dass ein Foreach viel einfacher wäre
Außerdem würde ich vorschlagen, dass Sie Eigenschaften hinzufügen, um auf Ihre Informationen zuzugreifen, anstatt auf öffentliche Felder. Abhängig von Ihrer .net-Version können Sie diese hinzufügen
public int MessageType {get; set;}
und diem_
öffentlichen Felder, Eigenschaften usw. entfernen, da sie nicht vorhanden sein sollten.quelle
Ich denke das hilft dir. Bitte prüfen
quelle