You can pass a property accessor to the method.
List<Class1> SortBy(List<Class1> toSort, Func<Class1, IComparable> getProp)
{
if (toSort != null && toSort.Count > 0) {
return toSort
.OrderBy(x => getProp(x))
.ToList();
}
return null;
}
You would call it like this:
var result = SortBy(toSort, x => x.maxSpeed);
But you could go one step further and write your own extension method.
public static class CollectionExtensions
{
public static List<TSource> OrderByAsListOrNull<TSource, TKey>(
this ICollection<TSource> collection, Func<TSource,TKey> keySelector)
if (collection != null && collection.Count > 0) {
return collection
.OrderBy(x => keySelector(x))
.ToList();
}
return null;
}
}
Now you can sort like this
List<Class1> sorted = toSort.OrderByAsListOrNull(x => x.maxSpeed);
but also
Person[] people = ...;
List<Person> sortedPeople = people.OrderByAsListOrNull(p => p.LastName);
Note that I declared the first parameter as ICollection<T>
because it must fulfill two conditions:
Count
propertyIEnumerable<T>
in order to be able to apply the LINQ method OrderBy
. List<Class1>
is an ICollection<T>
but also an array Person[]
as many other collections.
So far, I have shown how you can read a property. If the method needs to set a property, you need to pass it a setter delegate as well
void ReadAndWriteProperty(Func<Class1, T> getProp, Action<Class1, T> setProp)
Where T
is the type of the property.
You can use an lambda expression to pass property information:
void DoSomething<T>(Expression<Func<T>> property)
{
var propertyInfo = ((MemberExpression)property.Body).Member as PropertyInfo;
if (propertyInfo == null)
{
throw new ArgumentException("The lambda expression 'property' should point to a valid Property");
}
}
Usage:
DoSomething(() => this.MyProperty);
What I found missing from @MatthiasG's answer is how to get property value not just its name.
public static string Meth<T>(Expression<Func<T>> expression)
{
var name = ((MemberExpression)expression.Body).Member.Name;
var value = expression.Compile()();
return string.Format("{0} - {1}", name, value);
}
use:
Meth(() => YourObject.Property);
Great solution over here...
Passing properties by reference in C#
void GetString<T>(string input, T target, Expression<Func<T, string>> outExpr)
{
if (!string.IsNullOrEmpty(input))
{
var expr = (MemberExpression) outExpr.Body;
var prop = (PropertyInfo) expr.Member;
prop.SetValue(target, input, null);
}
}
void Main()
{
var person = new Person();
GetString("test", person, x => x.Name);
Debug.Assert(person.Name == "test");
}
Why don't you use Linq for this? Like:
vehicles.OrderBy(v => v.maxSpeed).ToList();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With