C#: Func <T, TResult> для общих методов

Возможно создать a Func возразить что ссылки общий метод? как LINQ OrderBy:

public static IOrderedEnumerable OrderBy(
    this IEnumerable source,
    Func keySelector
)

5
задан SDReyes 14 May 2010 в 16:41
поделиться

6 ответов

Если я правильно вас понял, вы спрашиваете, можно ли ссылаться на общий метод из анонимного метода.

Ответ - да.

Например, предположим, вам нужна Func, которая возвращает элементы объекта IEnumerable в отсортированном порядке (точно как OrderBy). Вы можете сделать так:

Func<IEnumerable<int>, Func<int, int>, IOrderedEnumerable<int>> orderByFunc =
    System.Linq.Enumerable.OrderBy<int, int>;

Затем вы можете использовать эту Func так же, как и любую другую:

int[] ints = new int[] { 1, 3, 5, 4, 7, 2, 6, 9, 8 };

// here you're really calling OrderBy<int, int> --
// you've just stored its address in a variable of type Func<...>
foreach (int i in orderByFunc(ints, x => x))
    Console.WriteLine(i);

Выход:

1
2
3
4
5
6
7
8
9

С другой стороны, если вы спрашиваете, можно ли создать "общий анонимный метод", например, так:

Func<T> getDefault<T> = () => default(T);

Тогда это зависит от вашего контекста. Это можно сделать в контексте, где T уже объявлен как параметр общего типа - а именно, в общем классе или общем методе. (См. ответ Фредди Риоса.) Вне такого контекста, к сожалению, это незаконно.

20
ответ дан 18 December 2019 в 06:34
поделиться

Да, но это зависит от контекста - если вы уже работаете с дженериками, просто используйте T в контексте / если нет, то вы уже знаете конкретный тип. В более позднем случае, если вам нужно повторно использовать немного логики в методе, вы, вероятно, уже выиграете от переноса этой логики в метод, так что просто сделайте как в моем втором примере ниже.

2 примера:

public T Something<T>() {
    Func<T> someFunc = () => { return default(T); };
    return someFunc();
}

public Func<T> GetDefaultCreator<T>() {
    return () => { return default(T); };
}
4
ответ дан 18 December 2019 в 06:34
поделиться

Что-то вроде этого?

Func, string> myFunc = c => c.HasValue ? c.ToString() : "null";

Это успешно компилируется, и вы можете назначить любую функцию, которая принимает Nullable и возвращает строку.

0
ответ дан 18 December 2019 в 06:34
поделиться

Я думаю, что я понимаю это: Учитывая функцию static TResult DoSomeStuff(T obj), можете ли вы создать Func таким образом, что он будет ссылаться на функцию выше, без параметров типа, указанных при создании ссылки на нее.
Я думаю, что это может сработать (Вы можете протестировать его, у меня нет C# рядом со мной на данный момент):

класс UselessClass
{
 Если это статический метод, это нормально:
 public Func DaFunc = RelevantClass.DoSomeStuff;
 Если нет, то необходимо что-то вроде этого:
 public UselessClass(SomeClassWhereTheFunctionIs from)
 {
 ДаФунк = от. DoSomeStuff;
 }
}

Кроме того, в OrderBy это на самом деле не общий делегат. Это объявление переменной. Когда ему дана функция, из нее выводятся типы.

0
ответ дан 18 December 2019 в 06:34
поделиться

Я сделал что-то вроде этого:

public static class Helper{

public static IEnumerable<KeyValuePair<string, string>> ToPairs(this NameValueCollection Form)
        {
            return Form.AllKeys.Cast<string>()
                .Select(key => new KeyValuePair<string, string>(key, Form[key]));
        }
}

Где этот метод стал методом расширения для request.form в веб-разработке на C #.

0
ответ дан 18 December 2019 в 06:34
поделиться

Да, это возможно, но вам нужно указать аргумент (ы) типа

func<int> f = myClass.returnsT<int>;

, где

class myClass
{
   T returnsT<T>()
   {...}
}

он не будет работать без аргументов типа

0
ответ дан 18 December 2019 в 06:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: