Ce qui suit est un extrait de mon 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;
}
J'essaie d'utiliser ce qui suit dans mon code de fonction main ():
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;
}
Le problème est ici: j'essaie d'imprimer tous les éléments de ma liste en utilisant une boucle for:
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);
}
Je veux trouver le dernier élément pour que j'assimile cnt3 dans ma boucle for et que j'imprime toutes les entrées de la liste. Chaque élément de la liste est un objet de la classe AllIntegerIDs comme mentionné ci-dessus dans l'exemple de code. Comment trouver la dernière entrée valide dans la liste?
Dois-je utiliser quelque chose comme integerList.Find (integerList []. M_MessageText == null;
Si j'utilise cela, il faudra un index qui va de 0 à n'importe quel maximum. Cela signifie que je devrai utiliser une autre boucle for que je n'ai pas l'intention d'utiliser. Existe-t-il un moyen plus court / meilleur?
Merci, Viren
AllIntegerIDs newItem = new AllIntegerID();
, utilisez cela pour attribuer tous les champs, puis appelezintegerList.Add(newItem)
. Ou utilisez des propriétés plutôt que des champs et utilisez la syntaxe d'initialisation d'objet C # 3.0.Réponses:
Si vous souhaitez simplement accéder au dernier élément de la liste, vous pouvez le faire
pour obtenir le nombre total d'éléments dans la liste, vous pouvez utiliser la propriété Count
la source
Last
/LastOrDefault
comme mentionné ci-dessous.Enumerable.Last
lèvera une exception si la liste est vide. Si vous appelezEnumerable.LastOrDefault
et transmettez une liste de types de valeurs, la valeur par défaut sera renvoyée si la liste est vide. Donc, si vous récupérez 0 à partir d'un,List<int>
vous ne saurez pas si la liste était vide ou si la dernière valeur était 0. En bref, vous devez vérifier leCount
mécanisme de récupération que vous décidez d'utiliser.var element = list[list.Count - 1]
c'est très succinct et lisible. Pas besoin d'invoquer des méthodes d'extensionPour obtenir le dernier élément d'une collection, utilisez les méthodes d'extension LastOrDefault () et Last ()
OU
N'oubliez pas d'ajouter
using System.Linq;
, sinon cette méthode ne sera pas disponible.la source
First
,FirstOrDefault
,Last
,LastOrDefault
,Single
,SingleOrDefault
,ElementAt
etElementAtOrDefault
sont optimisés pourIList<TSource>
,Count
etContains
sont optimisés pourICollection<TSource>
etCast<TResult>
est optimisé pourIEnumerable<TResult>
.using System.Linq;
System.Linq.Enumerable
ne sont pas vraiment «optimisées». Voici le code de laEnumerable.Last
méthode.System.Linq.Enumerable.Last
, je suis d'accord avec 0b101010 - leLast()
code n'est pas "optimisé pourList<>
s" -Last()
est juste un vilain wrapper, qui est par défaut aureturn list[list.Count-1]
cas où l'argument est unIList
, et itère sur la liste jusqu'à la fin au cas où ce n'est pas ... ce qui en fait une très mauvaise solution si leIList
est aLinkedList
, car l'indexeur passera inutilement par la liste entière (je n'ai pas trouvé de remplacement itérant à l'enversItem[]
avec index> Count / 2 dans les sources c #, YMMV )Allons à la racine de la question, comment aborder le dernier élément d'une liste en toute sécurité ...
En supposant
ensuite
"count-1" est une mauvaise habitude à moins que vous ne garantissiez d'abord que la liste n'est pas vide.
Il n'y a pas de moyen pratique de vérifier la liste vide, sauf pour le faire.
Le moyen le plus court auquel je puisse penser est
vous pouvez tout mettre en œuvre et créer un délégué qui renvoie toujours vrai, et le transmettre à FindLast, qui renverra la dernière valeur (ou la valeur construite par défaut si la liste est vide). Cette fonction commence à la fin de la liste ainsi sera Big O (1) ou temps constant, bien que la méthode soit normalement O (n).
La méthode FindLast est moche si vous comptez la partie déléguée, mais elle n'a besoin d'être déclarée qu'à un seul endroit. Si la liste est vide, elle renverra une valeur construite par défaut du type de liste "" pour chaîne. Il serait plus utile de pousser plus loin le délégué alwaysTrue, en en faisant un modèle au lieu d'un type chaîne.
la source
myList.FindLast(_unused_variable_name => true);
cela fonctionnera quel que soit le type. Une version plus courte estmyList.FindLast(_ => true);
, mais je trouve que le trait de soulignement (ou tout autre identificateur de caractère unique) peut parfois être un peu déroutant.la source
Changement
à
la source
Utilisez la
Count
propriété. Le dernier index seraCount - 1
.la source
Vous pouvez le trouver en comptant d'abord le nombre d'éléments dans la liste, par exemple
Ensuite, vous pouvez indexer le nombre - 1 pour obtenir le dernier élément de la liste, par exemple
la source
En C # 8.0, vous pouvez obtenir le dernier élément avec l' explication complète de l' opérateur ^
la source
Pourquoi ne pas simplement utiliser la propriété Count sur la liste?
la source
Indépendamment de votre question d'origine, vous obtiendrez de meilleures performances si vous capturez des références à des variables locales plutôt que de les indexer plusieurs fois dans votre liste:
Et dans votre
for
boucle:la source
Je devrais convenir qu'un foreach serait beaucoup plus facile quelque chose comme
Je vous suggère également d'ajouter des propriétés pour accéder à vos informations au lieu de champs publics, en fonction de votre version .net, vous pouvez l'ajouter comme
public int MessageType {get; set;}
et vous débarrasser dem_
vos champs publics, propriétés, etc.la source
Je pense que cela vous aide. Vérifiez s'il vous plaît
la source