Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Casting Func<T> to Func<object>

I'm trying to figure out how to pass Func<T> to Func<object> method argument:

public void Foo<T>(Func<T> p) where T: class
{
    Foo(p);
}

public void Foo(Func<object> p)
{

}

Strange thing, it works in NET 4.0 Class library, but doesn't work in Silverlight 4 Class library. Actually I want it to work in Silverlight, and I have input parameters like Func<T, bool>

like image 338
Alex Burtsev Avatar asked Jul 08 '11 12:07

Alex Burtsev


People also ask

What is func t TResult?

Func<T, TResult> defines a function that accepts one parameter (of type T) and returns an object (of type TResult). In your case, if you want a function that takes a Person object and returns a string...you'd want Func<Person, string> which is the equivalent of: string Function(Person p) { return p.Name; }

When to use Func in c#?

Func is generally used for those methods which are going to return a value, or in other words, Func delegate is used for value returning methods. It can also contain parameters of the same type or of different types.

How Func works in c#?

A Func in C# is a way to define a method in-line that has a return value. There is a similar concept of an Action that doesn't have a return value, but we'll get to that in a sec. The return value's type is always the last generic parameter on the Func 's definition.


2 Answers

This will do the trick:

public void Foo<T>(Func<T> p) where T : class
{
    Func<object> f = () => p();
    Foo(f);
}
like image 118
Steven Avatar answered Sep 19 '22 14:09

Steven


In C# 4.0 targeting .NET 4.0 (i.e. with variance) that is fine "as is", since there is a reference-preserving conversion from T : class to object. This is possible because Func<T> is actually defined as Func<out T>, making it covariant.

In previous versions of C#, or with C# 4.0 targeting earlier versions of .NET, you need to translate as per Steven's answer.

note, you will need disambiguation to prevent it being recursive! At the simplest, two method names. Or alternatively, Foo((Func<object>)p).

like image 29
Marc Gravell Avatar answered Sep 20 '22 14:09

Marc Gravell