Akram Shahda
Akram Shahda

Reputation: 14781

Is it possible to define how a type is used in OrderBy criteria

I have the following types:

public class Type1
{
    public Int32 ID { get; set; }
    public Decimal Value { get; get; }
}

public class Type2
{
    public Int32 ID { get; set; }
    public Type1 Type1 { get; set; }
}

I also have the following function:

List<Type2> GetOrderedType2List()    
{
    ...
    return type2List.OrderBy(type2 => type2.Type1).ToList();
}

I want instances of Type2 list to be ordered by their Type1 property according to Type1.Value values. However, I want to write code inside Type1 that specify how Type1 is used in OrderBy criteria.

Is that possible?

Appreciate your help.

Upvotes: 2

Views: 58

Answers (3)

msmolcic
msmolcic

Reputation: 6577

You can order by value returned from function defined inside your order by. I added some random logic, but you can implement whatever you want:

List<Type2> GetOrderedType2List()    
{
    ...
    return type2List.OrderBy(type2 =>
    {
        decimal orderValue;

        if (type2.Type1 == null)
            orderValue = 0;
        else if (type2.Type1.Value < 0)
            orderValue = Math.Abs(type2.Type1.Value);
        else
            orderValue = type2.Type1.Value;

        return orderValue;
    }).ToList();
}

Upvotes: 0

Rob
Rob

Reputation: 27367

You need to implement IComparable, like so:

public class Type1 : IComparable
{
    public Int32 ID { get; set; }
    public Decimal Value { get; set; }

    public int CompareTo(object obj) {
        var castObj = obj as Type1;
        if (castObj == null)
            return -1;
        return Value.CompareTo(castObj.Value);
    }
}

Testing:

var list = new List<Type2> { 
    new Type2 { Type1 = new Type1 { Value = 50 } }, 
    new Type2 { Type1 = new Type1 { Value = 2 } }, 
    new Type2 { Type1 = new Type1 { Value = 100 } }, 
    new Type2 { Type1 = new Type1 { Value = -10 } }
};

list.OrderBy(type2 => type2.Type1);

Gives the result:

-10, 2, 50, 100

Alternatively, you can opt to only compare against other Type1 objects (probably the best way to do it), and can do it like this:

public class Type1 : IComparable<Type1>
{
    public Int32 ID { get; set; }
    public Decimal Value { get; set; }

    public int CompareTo(Type1 obj) {
        if (obj == null)
            return -1;
        return Value.CompareTo(obj.Value);
    }
}

Upvotes: 1

serhiyb
serhiyb

Reputation: 4833

What about:

List<Type2> GetOrderedType2List()    
{
    ...
    return type2List.OrderBy(type2 => type2.Type1.Value).ToList();
}

Upvotes: 0

Related Questions