How can I find the last element in a List<>?

Viewed 559887

The following is an extract from my 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;
}

I am trying to use the following in my main() function code:

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;
}

Problem is here: I am trying to print all elements in my List using a for loop:

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);
}

I want to find the last element so that I equate cnt3 in my for loop and print out all entries in the List. Each element in the list is an object of the class AllIntegerIDs as mentioned above in the code sample. How do I find the last valid entry in the List?

Should I use something like integerList.Find(integerList[].m_MessageText == null;?

If I use that it will need an index that will range from 0 to whatever maximum. Means I will have to use another for loop which I do not intend to use. Is there a shorter/better way?

11 Answers

If you just want to access the last item in the list you can do

if (integerList.Count > 0)
{
   //  pre C#8.0 : var item = integerList[integerList.Count - 1];
   //  C#8.0 : 
   var item = integerList[^1];
}

to get the total number of items in the list you can use the Count property

var itemCount = integerList.Count;

In C# 8.0 you can get the last item with ^ operator full explanation

List<char> list = ...;
var value = list[^1]; 

// Gets translated to 
var value = list[list.Count - 1];
int lastInt = integerList[integerList.Count-1];

Change

for (int cnt3 = 0 ; cnt3 <= integerList.FindLastIndex ; cnt3++)

to

for (int cnt3 = 0 ; cnt3 < integerList.Count; cnt3++)

Though this was posted 11 years ago, I'm sure the right number of answers is one more than there are!

You can also doing something like;


if (integerList.Count > 0) 
   var item = integerList[^1];

See the tutorial post on the MS C# docs here from a few months back.

I would personally still stick with LastOrDefault() / Last() but thought I'd share this.

EDIT; Just realised another answer has mentioned this with another doc link.

Use the Count property. The last index will be Count - 1.

for (int cnt3 = 0 ; cnt3 < integerList.Count; cnt3++)

Why not just use the Count property on the List?

for(int cnt3 = 0; cnt3 < integerList.Count; cnt3++)

Independent of your original question, you will get better performance if you capture references to local variables rather than index into your list multiple times:

AllIntegerIDs ids = new AllIntegerIDs();
ids.m_MessageID = (int)IntegerIDsSubstring[IntOffset];
ids.m_MessageType = (int)IntegerIDsSubstring[IntOffset + 1];
ids.m_ClassID = (int)IntegerIDsSubstring[IntOffset + 2];
ids.m_CategoryID = (int)IntegerIDsSubstring[IntOffset + 3];
ids.m_MessageText = MessageTextSubstring;
integerList.Add(ids);

And in your for loop:

for (int cnt3 = 0 ; cnt3 < integerList.Count ; cnt3++) //<----PROBLEM HERE
{
   AllIntegerIDs ids = integerList[cnt3];
   Console.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}\n",
      ids.m_MessageID,ids.m_MessageType,ids.m_ClassID,ids.m_CategoryID, ids.m_MessageText);
}

I would have to agree a foreach would be a lot easier something like

foreach(AllIntegerIDs allIntegerIDs in integerList)
{
Console.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}\n", allIntegerIDs.m_MessageID,
allIntegerIDs.m_MessageType,
allIntegerIDs.m_ClassID,
allIntegerIDs.m_CategoryID,
allIntegerIDs.m_MessageText);
}

Also I would suggest you add properties to access your information instead of public fields, depending on your .net version you can add it like public int MessageType {get; set;} and get rid of the m_ from your public fields, properties etc as it shouldnt be there.

Related