Robert Pallin
Robert Pallin

Reputation: 139

C# Collection/List - Unique ID

In C# I'm trying to create a list of objects and when a new thing is added to the list, it is checked to make sure the same ID isn't used. I have the solution in Linq but I'm trying to do it without linq.

public void AddStudent(Student student)
        {
            if (students == null)                               
            {
                students.Add(student);                          
            }
            else
            {
                if ((students.Count(s => s.Id == student.Id)) == 1)   

                  // LINQ query, student id is unique
            {
                throw new ArgumentException("Error student " 
                  + student.Name + " is already in the class");
            }
            else
            {
                students.Add(student);
            }
        }
    }

Upvotes: 3

Views: 13270

Answers (8)

Dennis Traub
Dennis Traub

Reputation: 51634

You can override Student.Equals() and Student.GetHashCode() to check if the Student.Id is equal. If the student list inherits from List<Student>, you can just use the default Add() method. It will only add students with different Ids.

public class Student
{
    // ...

    public override bool Equals(object obj)
    {
        // Check for null values and compare run-time types.
        if (obj == null || GetType() != obj.GetType()) 
            return false;

        Student other = obj as Student;
        return this.Id == other.Id;
    }

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

public class StudentList : List<Student> { }

// Usage:

var students = new StudentList();
students.Add(student);

Upvotes: 2

Brad
Brad

Reputation: 12245

Another approach would be to use a HashSet instead of a List.

The Student class:

public class Student
{
    private int id;

    public override int GetHashCode()
    {
        return this.id;
    }
    public override bool Equals(object obj)
    {
        Student otherStudent = obj as Student;
        if (otherStudent !=null)
        {
            return this.id.Equals(otherStudent.id);
        }
        else
        {
            throw new ArgumentException();
        }

    }

    public int Id
    {
        get { return id; }
        set { id = value; }
    }

}

Then you can add stuff like this

    HashSet<Student> hashSetOfStudents = new HashSet<Student>();
    Student s1 = new Student() { Id = 1 };
    Student s2 = new Student() { Id = 2 };
    Student s3 = new Student() { Id = 2 };

    hashSetOfStudents.Add(s1);
    hashSetOfStudents.Add(s2);
    hashSetOfStudents.Add(s3);

The addition of s3 will fail because it has the same Id as s2.

Upvotes: 5

Christoffer
Christoffer

Reputation: 12910

A list of distinct items sounds awfully lot like a set

Update: Writing up a good motivation for how to select proper datastructures got a bit tedious, I'll just show you how you will write the above once you are more familiar with the .NET framework:

public void AddStudent(Student student)
{
    /* this.students is an ISet<Student> */
    if (!this.students.Add(student))
    {
       throw new ArgumentException("student");
    }
}

This of course assumes that Student has a suitable definition of Equals() and GetHashCode(). Depending on the concrete ISet type used you may actually get some nice side effects with a good definition of GetHashCode(), but that discussion is probably a bit out of the scope for this question.

Upvotes: 1

dknaack
dknaack

Reputation: 60448

Many ways to do that, here a two possible solutions

1. You can iterate through your list.

bool alreadyInList = false;
foreach (var item in students) 
{
 if (item.Id == student.Id)
 {
    alreadyInList = true;
    break; // break the loop
 }
}

if (!alreadyInList)
{
   students.Add(student);
} 
else
{
     throw new ArgumentException("Error student " 
              + student.Name + " is already in the class");
}

2. Override the Equals method in you Student object and check using Contains.

public class Student 
{
    public override bool Equals(object x) 
    {
        return ((Student)x).Id == this.Id;
    }
}

if (!students.Contains(student)) 
{
   students.Add(student);
} 
else 
{
     throw new ArgumentException("Error student " 
              + student.Name + " is already in the class");
}

More Information:

Upvotes: 0

m.qayyum
m.qayyum

Reputation: 411

First read all available id's into a list or array and then make sure that new id's don't match existing id's by checking list or array.

Upvotes: -1

Gustavo F
Gustavo F

Reputation: 2206

Use the foreach loop:

    public void AddStudent(Student student)
    {
        if (students == null)
        {
            students.Add(student);
        }
        else
        {
            foreach (var s in students)
            {
                if (student.Id == s.Id)
                {
                    throw new ArgumentException("Error student "
                    + student.Name + " is already in the class");
                }
            }
            students.Add(student);
        }
    }

Upvotes: 1

Micah Armantrout
Micah Armantrout

Reputation: 6971

I would use a Dictionary

students Dictionary<int, Student> = new Dictionary<int, Student>();

then check to see if you already have that student

if (!students.ContainsKey(student.id))
{
      students.add(student.id, student);
}

Upvotes: 1

ΩmegaMan
ΩmegaMan

Reputation: 31596

Make the structure to hold the students be a dictionary<int,Student> and check to see if the ID is already in the dictionary via ContainsKey.

Upvotes: 0

Related Questions