0

I would like to add classStudents to the list _ClassStudents only if classStudents is not yet in the list.

public class ClassStudents{

   public Id {get; set;}
   public Name {get; set;}
   public List<Student> Student {get; set;}

}



public static List<ClassStudents> _ClassStudentsList = new List<ClassStudents>();

  public static void addClassStudents(ClassStudents classStudents)
  {
          //if( classStudents isn't in ClassStudentsList ) <------
           _ClassStudentsList.Add(classStudents);
   }

How can I do this?

3
  • If turma is a type (user class) then follow the convention to use UpperCase (a.k.a. PascalCase) in order to distinguish it from the variable/field name turmas. Also addTurma is superfluous to the code and question. Commented Jul 30, 2017 at 14:09
  • what about value, can it be different? Commented Jul 30, 2017 at 14:11
  • 1
    'numericUpDown1.Value' can has any number up 0 but it can be repetited in list Commented Jul 30, 2017 at 14:13

3 Answers 3

6

You can use the Any extension method:

var text = nameClassStudents.Text;
if(!_ClassStudentsList.Any(t => t.Text == text))
{
    _ClassStudentsList.Add(new ClassStudents(text,(int)numericUpDown1.Value));
}

However, this does not guarantee that names will be unique in the list. If you want it guaranteed, you can simply use a Dictionary<string, int> instead of a List<ClassStudents>.
The Dictionary will not allow duplicate keys.
Of course, here you would also want to check if the key exists before adding a value to the dictionary:

var dict = new Dictionary<string, int>;
...

var text = nameClassStudents.Text;
if(!dict.ContainsKey(text))
(
    dict.Add(text, (int)numericUpDown1.Value);
)
Sign up to request clarification or add additional context in comments.

6 Comments

This assumes that each turma type will always contain two fields, one of which is the key. In the future you are boxing yourself in.
Yes, you are correct. That is my assumption. However, it's quite easy to use a Dictionary<string, turma> and just use the turma.Name as the key. A technique I've used before several times.
I was some days trying get a solution pt.stackoverflow.com/questions/225116/…
Right!, i would try to look for the item and if 0 values returned that means the item is not there
@ZoharPeled I edited your answer cause had to change the name of my variables and I'm trying to improve my questions to get questions unban
|
3

You can also use a HashSet:

public class ClassStudents {

   public Id {get; set;}
   public Name {get; set;}

   public override bool Equals(object obj) {
            return this.Name.Trim().ToLower().Equals(((ClassStudents)obj).Name.Trim().ToLower());
   }

   public override int GetHashCode() {
       return this.Name.GetHashCode();
   }
}

In your main(), you can declare a HashSet like below:

HashSet <ClassStudents> hash = new HashSet<ClassStudents>();

Now, this will add only unique elements in the set.

4 Comments

Thats a nice idea
Seems more complete answarenow
Yeah, a HashSet is probably a better option than a Dictionary.
2

I think the proper way is to tell your program what it means for two Turma types to be equal.

public class ClassStudents
{
    public string Name { get; set; }
    public int Value { get; set; }
    // Override the equality operation to check for text value only
    public override bool Equals(object obj)
    {
        if (obj is ClassStudents other) // use pattern matching
        {
            return Name.Equals(other.Name);
        }
        return false;
    }
}

Now you can use the list method .Contains() for checking if item exists.

{
    List<ClassStudents> classStudents = new List<ClassStudents>();

    public Test()
    {
        // Add three values
        classStudents.Add(new ClassStudents() { Name="ABC", Value=101 });
        classStudents.Add(new ClassStudents() { Name="IJK", Value=111 });
        classStudents.Add(new ClassStudents() { Name="XYZ", Value=101 });

        // Check if exists before adding this value
        ClassStudents x = new ClassStudents() { Name="ABC", Value=121 };
        // `Contains()` calls the `Equals()` method of `classStudents`
        if (!classStudents.Contains(x))
        {
            classStudents.Add(x);
        }
    }

}

This results in the cleanest code because it is obvious what the check if(!classStudents.Contains(x)) does. Also you are leveraging the power of the CLR by adding intelligence to your types. OOP is all about adding methods in your user classes to define actions. In this case, I am definition what equality means for this type and now the CLR can use this information where needed.

4 Comments

While you do make some good points, overriding equals should not be done just for the sake of one test. Equality for this list might not mean equality for other purposes, so I'm not sure that's the correct solution here. Also, using contains is no more readable then using Any. In fact, it's the other way around, since in the Any option you have the comparison condition right in front of you, and you don't need to guess if the equals method was overriden. One more thing, when overriding the equals method you should also override the GetHashCode method.
the problem with contains is that when you are using classes it will look for the same object and not an object with the same values
@Mike - actually no. Contains() checks if contents implement IEquatable and it uses this instead of a reference equality. I tested the code before I posted.
@ja72 I edited your answer cause had to change the name of my variables and I'm trying to improve my questions to get questions unban

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.