Могу ли я определить метод для принятия ЛИБО Func <T>ИЛИ Expression <Func <T>>? - PullRequest
7 голосов
/ 21 октября 2010

Если я попытаюсь написать две перегрузки метода, один из которых принимает параметр Expression<Func<T>>, а другой принимает Func<T>, я получу ошибку компилятора при попытке вызвать метод с лямбда-выражением, поскольку две сигнатуры неоднозначность. Следующее может быть проблематично, например:

Method(() => "Hello"); // Is that a Func<string>,
                       // or is it an Expression<Func<string>>?

Я понял. Но мне не нравится подход просто принять Expression<Func<string>>, так как это заставляет вызывающий код использовать лямбда-выражение. Что если я тоже хочу принять группу методов?

Моя основа для того, чтобы задать этот вопрос, состоит в том, что я работаю над кодом, в котором я хотел бы написать что-то вроде этого:

Method(() => "Hello");

... и получите вывод, подобный этому:

Executed '() => "Hello"' and got "Hello" back.

Между тем, я бы тоже хотел это сделать:

Method(ReturnHello);

... и получите вывод, подобный этому:

Executed 'ReturnHello' and got "Hello" back.

Есть ли способ сделать то, что я пытаюсь сделать, без использования двух разных имен методов (например, ExpressionMethod и FuncMethod)? Я понимаю, что это не было бы таким большим делом; Мне просто любопытно, есть ли другой способ.

Ответы [ 2 ]

1 голос
/ 22 октября 2010

Возможно создать один метод с двумя именованными параметрами со значениями по умолчанию null.

public static void Test<T>(Func<T> func = null, Expression<Func<T>> expression = null)
{
}

Я знаю, что вы упускаете ИЛИ в этом, но это легко проверить в методе.

1 голос
/ 22 октября 2010

Вы можете перегрузить метод, чтобы получить либо Func<T>, либо Expression<Func<T>>, но когда вы это сделаете, автоматическое определение типа завершится неудачно, поэтому вам нужно явно определить типы с помощью приведения.Вот так:

public static void Test()
{
    Test((Func<string>)(() => "helllo"));
    Test((Expression<Func<string>>) (() => "hello"));
}

public static void Test<T>(Func<T> func)
{

}

public static void Test<T>(Expression<Func<T>> expression)
{

}

Это не красиво.

...