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

查看:16
本文介绍了将属性本身传递为 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 属性的传递以进行进一步处理.使用恕我直言的最佳选择将是(或类似的东西):

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

推荐答案

您可以将属性访问器传递给方法.

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 因为它必须满足两个条件:

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

  1. 它必须有一个 Count 属性
  2. 它必须是 IEnumerable 才能应用 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 是一个 ICollection 也是一个数组 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 是属性的类型.

Where T is the type of the property.

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

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