简体   繁体   中英

List.clear() followed by List.add() not working

I have the following C# Class/Function:

    class Hand
    {

    private List<Card> myCards = new List<Card>();

    public void sortBySuitValue()
    {
        IEnumerable<Card> query = from s in myCards
                                  orderby (int)s.suit, (int)s.value
                                  select s;

        myCards = new List<Card>();
        myCards.AddRange(query);
    }
 }

On a card Game. This works fine, however, I had trouble at first, instead of using myCards = new List(); to 'reset' myCards, I would use myCards.clear(), however, once I called the clear function, I would not be able to call myCards.add() or myCards.addRange(). The count would stay at zero. Is my current approach good? Is using LINQ to sort my cards good/bad?

this would work

    class Hand
    {

    private List<Card> myCards = new List<Card>();

    public void sortBySuitValue()
    {
        myCards = (from s in myCards
                                  orderby (int)s.suit, (int)s.value
                                  select s).ToList();
    }
 }

The problem is that an IEnumerable is a query, not a list. Since it's selecting from myCards , if you clear myCards before actually executing the query, it'll return no results. You can run the query before clearing the list by using IEnumerable.ToList() thus:

public void sortBySuitValue()
{
    var query = (from s in myCards
                              orderby (int)s.suit, (int)s.value
                              select s).ToList();

    myCards.Clear();
    myCards.AddRange(query);
}

You don't need LINQ to sort, the List class already provides a Sort method which you can pass a Comparison delegate suitable for you. Example for sorting strings by length:

        List<string> myList = new List<string>( new string[] { "foo", "bar" } );

        myList.Sort((x, y) => 
        {
            if (x.Length == y.Length)
                return 0;
            else if (x.Length < y.Length)
                return 1;
            else return -1; 
        });

To myCards is filled with information that you get with the sentence LINQ need to Call some method such as .ToList() If you do not myCards will contain nothing.

This should work:

    class Hand
    {

    private List<Card> myCards = new List<Card>();

    public void sortBySuitValue()
    {
        myCards = (from s in myCards
                                  orderby (int)s.suit, (int)s.value
                                  select s).ToList();
    }

You can use LINQ to generate a query to create a new list (or repopulate a cleared list), but I'd rather use the Sort instance method of List<T> to go ahead and sort my existing list in place in this particular situation.

List<Card> myCards = SomeMethodGeneratingCards();

Comparison<Card> cardComparison = (card1, card2) =>
    {
        int value = card1.Suit.CompareTo(card2.Suit);
        if (value == 0)
            value = card1.Value.CompareTo(card2.Value);

        return value;
    };

myCards.Sort(cardComparison);

You can sort the data inplace in the list:

myCards.Sort( (l,r) => 
     l.suit.Equals(r.suit) ? l.value.CompareTo(r.value) : l.suit.CompareTo(r.suit));

This way you won't have to create a new list which is assigned to your old variable.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM