Селектор для определенного параметра в качестве входа для функции - PullRequest
0 голосов
/ 28 января 2020

У меня есть класс Point, который имеет несколько параметров.
Теперь у меня есть List из Points, который входит в определенную функцию. В качестве входного параметра я хочу указать функции, какой параметр следует использовать для определенного расчета.
Конечно, я мог бы что-то вроде

CalculateSomething(List<Point> points, List<double> points.Select(p => p.firstParameter))

, но это, очевидно, не очень умно, так как в Очки firstParameter уже включены. Есть ли способ просто дать что-то вроде Selector, сообщив функции, какой параметр ей следует использовать.
Было бы неплохо, если есть способ без enum, а затем множество случаев if. или switch-case -структуры.

using System;     
using System.Collections.Generic;  

public class Point
{
    public Point (...)
    { ... }

    public double x;
    public double y;

    public double firstParameter;
    public double secondParameter;
}            

public class Program
{
    public static void Main()
    {
        Point p1 = new Point(...);
        Point p2 = new Point(...);
        Point p3 = new Point(...);
        List<Point> points = new List<Point> { p1, p2, p3 };

        CalculateSomething(points, >>>SELECTOR<<<)
    }   

    public static double CalculateSomething(List<Point> points, >>>Selector selectedParameter<<<)
    {
        return points[0].x / points[0].y * points[0].selectedParameter;
    }   

}

Ответы [ 4 ]

2 голосов
/ 28 января 2020
public static double CalculateSomething(List<Point> points, Func<Point, double> selector)
{
    return points[0].x / points[0].y * selector(points[0]);
}

Тогда звоните так:

public static void Main()
{
    Point p1 = new Point(...);
    Point p2 = new Point(...);
    Point p3 = new Point(...);
    List<Point> points = new List<Point> { p1, p2, p3 };

    CalculateSomething(points, point => point.firstParameter);
}
1 голос
/ 28 января 2020

Метод будет как:

public static double CalculateSomething(List<Point> points, Func<Point, double> selector)
{
        return points[0].x / points[0].y * selector(points[0]);
}   

И вызов будет как:

CalculateSomething(points, (p) => p.firstParameter);
1 голос
/ 28 января 2020

Вы можете использовать Func<T, TResult> делегат для этого

public static double CalculateSomething(List<Point> points, Func<Point, double> selector)
{
    return points[0].x / points[0].y * selector(points[0]);
}

И пример использования

Func<Point, double> selector = point => point.firstParameter;
CalculateSomething(points, selector); 

или просто

CalculateSomething(points, point => point.firstParameter);
0 голосов
/ 28 января 2020

Решение Func<Point, double> из других ответов, вероятно, самый чистый метод, который вы найдете. Он не делает ТОЧНО того, что вы хотите, но он читабелен и не должен вызывать проблем, если вы или ваш пользователь кода обладаете минимальной дисциплиной кода.

Если вы ДЕЙСТВИТЕЛЬНО хотите сказать своему коду " используйте это свойство ", единственная опция, которую вы имеете, это Reflection.

Обратите внимание, что это всего лишь мысленный эксперимент, и вам, вероятно, не следует использовать такой код слегка. Это не для производительности.

public static double CalculateSomething(List<Point> points, PropertyInfo pointProperty)
{
    return points[0].x / points[0].y * pointProperty.GetValue(points[0]);
}

Использование:

using System.Reflection;

/* ... */

CalculateSomething(points, typeof(Point).GetProperty("propertyName"));
...