将属性本身传递给C#中的参数 [英] Pass property itself to function as parameter in C#

查看:151
本文介绍了将属性本身传递给C#中的参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一种将属性本身传递给函数的方法。不是财产的价值。函数事先不知道将使用哪个属性进行排序。此示例中最简单的方法是:创建4个具有不同参数类型的覆盖。另一种方法是在函数内部使用 typeof()。当Class1具有数百个属性时,这两种方式都是不可接受的。到目前为止,我发现了以下方法:

I am looking for a method to pass property itself to a function. Not value of property. Function doesn't know in advance which property will be used for sorting. Simplest way in this example is: creating 4 overwrites with different parameter types. Other way is using of typeof() inside function. Both these ways are unacceptable when Class1 has hundreds properties. So far I found following method:

class Class1
{
    string vehName;
    int maxSpeed;
    int fuelCapacity;
    bool isFlying;
}

class Processor
{
    List<Class1> vehicles = null;
    Processor(List<Class1> input)
    {
        vehicles = input;
    }

    List<Class1> sortBy(List<Class1> toSort, string propName)
    {
        if (toSort != null && toSort.Count > 0)
        {
            return toSort.OrderBy(x => typeof(Class1).GetProperty(propName).GetValue(x, null)).ToList();
        }
        else return null;
    }
}

class OuterUser
{
    List<Class1> vehicles = new List<Class1>();
    // ... fill the list
    Processor pr = new Processor(vehicles);
    List<Class1> sorted = pr.sortBy("maxSpeed");
}

我不喜欢这种方法,因为存在人为错误的风险将字符串传递给处理函数。当字符串是由代码的其他部分生成时,这将变得更加难看。
请提出更优雅的方法来实现Class1属性的传递,以进行进一步处理。使用IMHO的最佳选择是(或类似的东西):

I don't like this method because of risk of "human error" when passing string to processing function. When the string is generated by other part of code this is going be even more ugly. Please, suggest more elegant way to implement passing of Class1 property to function for further processing. The best option for usage IMHO will be (or something like this):

vehicles = sortBy(vehicles, Class1.maxSpeed);


推荐答案

您可以将属性访问器传递给方法。 / p>

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;
}

您会这样称呼:

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;
    }
}

现在您可以像这样

List<Class1> sorted = toSort.OrderByAsListOrNull(x => x.maxSpeed);

而且还有

Person[] people = ...;
List<Person> sortedPeople = people.OrderByAsListOrNull(p => p.LastName);

请注意,我将第一个参数声明为 ICollection< T> ,因为它必须满足两个条件:

Note that I declared the first parameter as ICollection<T> because it must fulfill two conditions:


  1. 它必须具有 Count 属性

  2. 必须是 IEnumerable< T> ,才能应用LINQ方法 OrderBy

  1. It must have a Count property
  2. It must be an IEnumerable<T> in order to be able to apply the LINQ method OrderBy.

List< Class1> ICollection < T> 以及其他许多集合的数组 Person []

List<Class1> is an ICollection<T> but also an array Person[] as many other collections.

到目前为止,我已经展示了如何读取属性。如果该方法需要设置属性,则还需要向其传递一个setter委托

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)

其中 T 是属性的类型。

这篇关于将属性本身传递给C#中的参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆