44

Can a method in C# return a method?

A method could return a lambda expression for example, but I don't know what kind of type parameter could I give to such a method, because a method isn't Type. Such a returned method could be assigned to some delegate.

Consider this concept as an example:

public <unknown type> QuadraticFunctionMaker(float a , float b , float c)
{
    return (x) => { return a * x * x  + b * x + c; };
}

delegate float Function(float x);
Function QuadraticFunction = QuadraticFunctionMaker(1f,4f,3f);
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Miro
  • 1,778
  • 6
  • 24
  • 42

5 Answers5

52

The Types you are looking for are Action<> or Func<>.

The generic parameters on both types determine the type signature of the method. If your method has no return value use Action. If it has a return value use Func whereby the last generic parameter is the return type.

For example:

public void DoSomething()                          // Action
public void DoSomething(int number)                // Action<int>
public void DoSomething(int number, string text)   // Action<int,string>

public int DoSomething()                           // Func<int>
public int DoSomething(float number)               // Func<float,int>
public int DoSomething(float number, string text)  // Func<float,string,int>
Serplat
  • 4,367
  • 2
  • 18
  • 20
Zebi
  • 8,682
  • 1
  • 36
  • 42
27
public Func<float, float> QuadraticFunctionMake(float a, float b, float c) {
    return x => a * x * x + b * x + c;
}

The return type is Func<float, float>.

siride
  • 200,666
  • 4
  • 41
  • 62
3

<unknown type> = Function. That is,

public Function QuadraticFunctionMaker(float a , float b , float c)
{
    return (x) => { return a * x * x  + b * x + c; };
}

Is what you’re looking for since you’ve already declared the delegate Function to match. Alternatively, you don’t need to declare a delegate at all and can use Func<float, Float> as noticed by others. This is exactly equivalent. In fact, Func<T, T> is declared in exactly the same way as your delegate Function except that it’s generic.

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
  • 1
    It's better to use things like `Func<>` and `Action<>`. I believe MS is moving away from having custom delegates all over the place. – siride Jul 03 '11 at 14:37
  • 1
    @siride: no it's not. When you want to make your intent explicit, a strongly defined delegate is better – Jeff Jul 03 '11 at 14:38
  • @JeffN825: the problem is that you can't easily pass custom delegates around in contexts that don't explicitly expect that kind of delegate. If .NET had the ability to have delegate hierarchies or traits or something vaguely useful, I'd agree with you. Otherwise, it's just a pain to use anything other than the generic versions. – siride Jul 03 '11 at 14:43
  • 1
    Sure you can, as long as the signature matches. And passing around an Action which takes six parameters simply named p1 through p6 is pretty confusing as to intent if you ask me. – Jeff Jul 03 '11 at 15:04
  • @JeffN825: I agree, but only because the delegate system in .NET sucks. But rather than make it suck more by having named delegates that add little and make life more complicated due to needless incompatibility between delegates having the same parameter and return types. – siride Jul 03 '11 at 15:40
0

Your lambda expressions would take a float as a parameter (I believe), and then return a float as well. In .NET, we can represent this by the type Func<float, float>.

Generally, if you're dealing with lambdas that take more parameters, you can use Func<Type1, Type2, Type3, ..., ReturnType>, with up to eight parameters.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Ken Wayne VanderLinde
  • 18,915
  • 3
  • 47
  • 72
-6

You can use the dynamic keyword. See dynamic (C# Reference).

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Ahmed Magdy
  • 5,956
  • 8
  • 43
  • 75