Rajat Shrestha
Rajat Shrestha

Reputation: 63

How to pass a attribute as parameter in C#?

I need to implement a sort using 4 different attributes in a same object type in C#.

lets say the object Student has name, id, birthdate and grade. How do i reuse the code for sorting each of them. I have managed to sort by name, how do i reuse the code?

private void btnSortName_Click(object sender, EventArgs e)
    {
        Student obj = new Student();
        List<Student> listOfStudents = obj.List();
        int student_count = listOfStudents.Count();
        int first_index, last_index;

        for (first_index = 1; first_index < student_count; first_index++)
        {
            last_index = first_index - 1;
            Student first = listOfStudents[first_index];
            Student last = listOfStudents[last_index];

            while (last_index >= 0 && DateTime.Compare(last.RDate, first.RDate) > 0)
            {
                listOfStudents[last_index + 1] = listOfStudents[last_index];
                last_index = last_index - 1;
            }
            listOfStudents[last_index + 1] = first;
        }
        DataTable dt = Utility.ConvertToDataTable(listOfStudents);
        dataGridStudents.DataSource = dt;
        btnSortName.Visible = false;
        btnSortName.Enabled = false;
        btnSortNameD.Visible = true;
        btnSortNameD.Enabled = true;
    }

I have tried doing this by creating a method for insertion sort and passing attribute as parameter and returns list of that object but both of these are showing errors:

public List<Student> insertion_Sort(ref String data, Boolean asc)
    {
        Student obj = new Student();
        List<Student> listOfStudents = obj.List();
        int student_count = listOfStudents.Count();
        int first_index, last_index;

        for (first_index = 1; first_index < student_count; first_index++)
        {
            last_index = first_index - 1;
            Student first = listOfStudents[first_index];
            Student last = listOfStudents[last_index];

            if (asc){
                while (last_index >= 0 && DateTime.Compare(last.data, first.data) > 0)
                {
                    listOfStudents[last_index + 1] = listOfStudents[last_index];
                    last_index = last_index - 1;
                }
                listOfStudents[last_index + 1] = first;
            }
            else
            {
                while (last_index >= 0 && DateTime.Compare(last.data, first.data) < 0)
                {
                    listOfStudents[last_index + 1] = listOfStudents[last_index];
                    last_index = last_index - 1;
                }
                listOfStudents[last_index + 1] = first;
            }
        }
        return listOfStudents;
    }

returntype

attribute as parameter

How do i fix these issues?

Upvotes: 2

Views: 237

Answers (2)

voidengine
voidengine

Reputation: 2579

A standard way to customize sorting would be by supplying an IComparer<T> to the sorting algorithm.

  • modify your sort to accept an IComparer<Student>. Replace your comparisons in the sort by call to comparer.Compare(). As a bonus, you can make your sort generic.

  • create an implementation of IComparer<Student> for each way you want to sort the Student objects. The easiest way to do that is to use Comparer.Create():

    var nameComparer = Comparer<Student>.Create((studentA, studentB) => string.Compare(studentA.Name, studentB.Name));
    var gradeComparer = Comparer<Student>.Create((studentA, studentB) => studentA.grade.CompareTo(studentB.grade));
    

It's the same as how List<T>.Sort() and Array.Sort() allow to customize sorting.

Upvotes: 1

Atreyagaurav
Atreyagaurav

Reputation: 1195

Your 2nd error is because you can't do obj.attribute while attribute is a string with attribute name. use something like obj.GetType().GetProperty(propertyName).GetValue(obj, null) to get the the attribute by name..

Maybe this will work, try it as I don't have your student data or a c# compiler at the moment to check.. Comment what it outputs.

public List<Student> insertion_Sort(List<Student> listOfStudents,ref String propertyName, Boolean asc)
    {
        Student obj = listOfStudents [0];
        int student_count = listOfStudents.Count();
        int first_index, last_index;
        dynamic prop= obj.GetType().GetProperty(propertyName);
        for (first_index = 1; first_index < student_count; first_index++)
        {
            last_index = first_index - 1;
            Student first = listOfStudents[first_index];
            Student last = listOfStudents[last_index];

            if (asc){
                while (last_index >= 0 && prop.GetValue(first, null)-prop.GetValue(last, null) > 0)
                {
                    listOfStudents[last_index + 1] = listOfStudents[last_index];
                    last_index = last_index - 1;
                }
                listOfStudents[last_index + 1] = first;
            }
            else
            {
                while (last_index >= 0 && prop.GetValue(first, null)-prop.GetValue(last, null) <0)
                {
                    listOfStudents[last_index + 1] = listOfStudents[last_index];
                    last_index = last_index - 1;
                }
                listOfStudents[last_index + 1] = first;
            }
        }
        return listOfStudents;
    }

Upvotes: 1

Related Questions