0

The following code, sorts any array of objects by any property name (as string) exists in the object.

Sorting array is done using sorting direction "asc" or "desc" too.

This is the goal I want to apply.

    using System.Linq.Dynamic;

    /// <summary>
    /// This method sorts any array of objects.
    /// </summary>
    /// <param name="dataSource">Array of objects</param>
    /// <param name="propertyName">property name to sort with</param>
    /// <param name="sortDirection">"ASC" or "DESC"</param>
    /// <returns></returns>
    private object[] SortArrayOfObjects(object[] dataSource, string propertyName, string sortDirection)
    {
        string sortExpression = string.Format("{0} {1}", propertyName, sortDirection);
        // sortExpression will be something like "FirstName DESC".

        // OrderBy method takes expression as string like "FirstName DESC".
        // OrderBy method exists in "System.Linq.Dynamic" dll.
        // Download it from www.nuget.org/packages/System.Linq.Dynamic/
        object[] arrSortedObjects = dataSource.OrderBy(sortExpression).ToArray();

        return arrSortedObjects;
    }
3
  • 1
    You won't be able to use LINQ after that - and it doesn't make sense that you would, because you have effectively lost the type information (You couldn't write, for example: newArrEmpInfo.Where(e => e.Id == 5) because 1. You no longer know if newArrEmpInfo is an IEnumerable, and 2. You do not know that there is an Id property on any of the objects in the collection - or that it's even an int). Could you provide more information as to what you're trying to accomplish? (Your goal; not implementation) Commented Aug 5, 2015 at 0:17
  • Convert.ChangeType is as good as if your type supports IConvertible and more of a value type(struct, still not applicable to all). May be you should look at Dapper dot net type conversion or just wait I'll try to write something meanwhile. Commented Aug 5, 2015 at 0:44
  • The type of variables is a compile-time concept. Your declaration objType newArrEmpInfo makes zero sense, as does the cast, because the object referenced by dataSource already is whatever type it is. Indeed, the call Convert.ChangeType() does nothing because the dataSource is already the run-time type you're asking the method to change it to. Whatever it is you're actually trying to do, you need to explain better so we can actually understand your question. The question you asked here doesn't make any sense at all. Commented Aug 5, 2015 at 3:08

1 Answer 1

1

You can do what you want by making the method generic to accept a type from the calling method, and then using type parameter T to cast the dataSource to.

private object[] SortArrayOfObjects<T>(object[] dataSource, string propertyName, string sortDirection)
    {
        string sortExpression = string.Format("{0} {1}", propertyName, sortDirection);
        // sortExpression will be something like "FirstName DESC".

        // OrderBy method takes expression as string like "FirstName DESC".
        // OrderBy method exists in "System.Linq.Dynamic" dll.
        // Download it from www.nuget.org/packages/System.Linq.Dynamic/
        object[] arrSortedObjects = dataSource.Cast<T>().OrderBy(sortExpression).Cast<object>().ToArray();

        return arrSortedObjects;
    }
}

// Use it like:       | You pass the type, so no need for hardcoding it, and it should work for all types.
SortArrayOfObjects<EmployeeInfo>(object[] dataSource, string propertyName, string sortDirection);

Here is a complete demonstration:

Put this in a project of DLL output: using System; using System.Collections.Generic; using System.Text; using System.Collections.Generic; using System.Linq; using System.Linq.Dynamic;

namespace GenericMethod
{
    public class GenericMethodClass
    {
        public T[] SortArrayOfObjects<T>(object[] dataSource, string propertyName, string sortDirection)
        {
            string sortExpression = string.Format("{0} {1}", propertyName, sortDirection);
            // sortExpression will be something like "FirstName DESC".

            // OrderBy method takes expression as string like "FirstName DESC".
            // OrderBy method exists in "System.Linq.Dynamic" dll.
            // Download it from www.nuget.org/packages/System.Linq.Dynamic/
            T[] arrSortedObjects = dataSource.Cast<T>().OrderBy(sortExpression).ToArray();

            return arrSortedObjects;
        }
    }
}

Put this in a console app project and make sure to reference the library containing the code above: using System; using System.Collections.Generic; using System.Text; using GenericMethod; using System.Linq;

namespace GenericMethodApp
{
    public class Program
    {
        static void Main(string[] args)
        {
            var employees = new object[]
            {
                new EmployeeInfo { FirstName = "Mohammed" },
                new EmployeeInfo { FirstName = "Ghasan" }
            };

            var students = new object[]
            {
                new Student { StudentName = "Mike" },
                new Student { StudentName = "Harris" }
            };

            var genericMethodClass = new GenericMethodClass();

            // Note that the generic method returns the array of the specific type
            // thanks to the T type parameter.
            EmployeeInfo[] returnedEmployees = genericMethodClass.SortArrayOfObjects<EmployeeInfo>(employees, "FirstName", "ASC");
            Student[] returnedStudents = genericMethodClass.SortArrayOfObjects<Student>(students, "StudentName", "ASC");

            foreach (var employee in returnedEmployees)
                Console.WriteLine(employee.FirstName);

            Console.WriteLine();

            foreach (var Student in returnedStudents)
                Console.WriteLine(Student.StudentName);

            Console.ReadKey();
        }
    }

    public class EmployeeInfo
    {
        public string FirstName { get; set; }
    }

    public class Student
    {
        public string StudentName { get; set; }
    }
}

You are done.

Make sure to reference System.Linq.Dynamic inside the DLL.

Sign up to request clarification or add additional context in comments.

7 Comments

The method 'SortArrayOfObjects<T>' will be put inside a dll and I want to call it from the dll itself. EmployeeInfo is declared in UI Layer. How can I call it?
@MohammedOsman No problem. In the dll you will put the generic SortArrayOfObjects<T> (no reference to EmployeeInfo), and when calling it from UI (thus you have access to EmployeeInfo), you can just call it like this SortArrayOfObjects<EmployeeInfo>. And in another project, you can do SortArrayOfObjects<DepartmentInfo>. The method is generic, and as long as you have access to the type, you have no issue. It works for all of them.
@Ghsan I want to create a function named public void ProcessArray(object[] dataSource, string propertyName, string sortDirection) inside the class GenericMethodClass that calls the function SortArrayOfObjects<T>(object[] dataSource, string propertyName, string sortDirection) How can I do this? This is the goal to call the sort method from the dll not from UI layer.
@MohammedOsman You cannot do what you want. You have to tell the compiler the Type you want to cast to. I want to understand why you would want to achieve this, what is the problem with calling SortArrayOfObjects<T>(object[] dataSource, string propertyName, string sortDirection) inside the UI directly?
@Ghsan I'm doing a custom control CustomGridView : GridView which takes object[] of as data source. I want to handle sorting of the grid in my custom GridView. Some people says that I can do sorting by Reflection. But when I knew System.Linq.Dynamic, I liked to use it.
|

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.