Can a lambda expression be declared and invoked at the same time in C#? - c#

In VB.NET, a lambda expression can be declared and invoked on the same line:
'Output 3
Console.WriteLine((Function(num As Integer) num + 1)(2))
Is this possible in C#?

You have to tell the compiler a specific delegate type. For example, you could cast the lambda expression:
Console.WriteLine(((Func<int, int>)(x => x + 1))(2));
EDIT: Or yes, you can use a delegate creation expression as per Servy's answer:
Console.WriteLine(new Func<int, int>(i => i + 1)(2));
Note that this isn't really a normal constructor call - it's special syntax for delegate creation which looks like a regular constructor call. Still clever though :)
You can make it slightly cleaner with a helper class:
public static class Functions
{
public static Func<T> Of<T>(Func<T> input)
{
return input;
}
public static Func<T1, TResult> Of<T1, TResult>
(Func<T1, TResult> input)
{
return input;
}
public static Func<T1, T2, TResult> Of<T1, T2, TResult>
(Func<T1, T2, TResult> input)
{
return input;
}
}
... then:
Console.WriteLine(Functions.Of<int, int>(x => x + 1)(2));
Or:
Console.WriteLine(Functions.Of((int x) => x + 1)(2));

Console.WriteLine(new Func<int, int>(i => i + 1)(2));
Uses a few less parentheses to use the Func's constructor than a cast.

Yes, though it's messy:
Console.WriteLine(((Func<int, int>) (num => num + 1))(2));

Kind or, you would have to use the Func object :
var square = new Func<double, double>(d => d*d)(2);
Console.WriteLine(square);

Related

How to cast Predicate<T> to Func<T, bool> [duplicate]

I have a class with a member Predicate which I would like to use in a Linq expression:
using System.Linq;
class MyClass
{
public bool DoAllHaveSomeProperty()
{
return m_instrumentList.All(m_filterExpression);
}
private IEnumerable<Instrument> m_instrumentList;
private Predicate<Instrument> m_filterExpression;
}
As I read that "Predicate<T> is [...] completely equivalent to Func<T, bool>" (see here), I would expect this to work, since All takes in as argument: Func<Instrument, bool> predicate.
However, I get the error:
Argument 2: cannot convert from 'System.Predicate<MyNamespace.Instrument>' to 'System.Type'
Is there a way to convert the predicate to an argument that this function will swallow?
The two types represent the same logical signature, but that doesn't mean they're just interchangable. A straight assignment won't work, for example - but you can create a new Func<T, bool> from the Predicate<T, bool>. Sample code:
Predicate<string> pred = x => x.Length > 10;
// Func<string, bool> func = pred; // Error
Func<string, bool> func = new Func<string, bool>(pred); // Okay
This is a bit like having two enum types with the same values - you can convert between them, but you have to do so explicitly. They're still separate types.
In your case, this means you could write:
public bool DoAllHaveSomeProperty()
{
return m_instrumentList.All(new Func<T, bool>(m_filterExpression));
}
The lambda expression approach suggested by other answers will work too, of course.
public bool DoAllHaveSomeProperty()
{
return m_instrumentList.All(i => m_filterExpression(i));
}
You can convert a predicate to a method by calling Invoke. All delegates have this member. Delegates don't have structural identity, but methods can be converted to matching delegates. This fix has a minor performance cost, as it adds an extra layer of indirection. However, most solutions to this problem have that problem. Eric Lippert discusses this in more detail at https://web.archive.org/web/20140625132124/http://blog.coverity.com/2014/06/18/delegates-structural-identity/ .
In your specific case, replace return m_instrumentList.All(m_filterExpression); with return m_instrumentList.All(m_filterExpression.Invoke);
Sample code demonstrating the actual problem.
void Main()
{
Predicate<int> t1 = Foo;
Func<int,bool> t2 = Foo;
Predicate<int> t3 = t2.Invoke; //Legal
Func<int,bool> t4 = t1.Invoke; //Legal
Predicate<int> t5 = t2; //Illegal
Func<int,bool> t6 = t1; //Illegal
}
bool Foo(int x)
{
return x > 20;
}
return m_instrumentList.All(i => m_filterExpression(i));
Since there are a lot of answers i will add one more just for fun.
If you want your code to compile you can use extention methods
//Original Code
class MyClass4
{
public bool DoAllHaveSomeProperty()
{
return m_instrumentList.All(m_filterExpression);
}
private IEnumerable<Instrument> m_instrumentList;
private Predicate<Instrument> m_filterExpression;
}
Add this class in the same namespace
public static class MyExtentions
{
public static bool All(this IEnumerable<Instrument> enumer, Predicate<Instrument> pred)
{
return enumer.All(e => pred(e));
}
}
As Brian said, you can convert a predicate to a method via Invoke:
public bool DoAllHaveSomeProperty()
{
return m_instrumentList.All(m_filterExpression.Invoke);
}

Compile Error 'cannot convert' on Declared Delegate

I'm having issues when passing a delegate as a Where parameter in LINQ.
I'm declaring a delegate in the namespace:
public delegate bool FilterInt<in T>(T x);
I've made a method to assign to the delegate and then assign it:
public static bool FilterData(int val)
{
if (val < 10)
return true;
return false;
}
When I try to filter a List using the delegate I get a compile time error 'Cannot conver from FilterInt to Func<Int, bool>:
listInt.Where(_filterer);
However, I can use the below (an implied delegate?) without any issues:
listInt.Where(FilterData);
I have the same issue with _comparer when I follow the MSDN doc on delegates here if I define my own delegate in the namespace as per the below:
public delegate int Comparison<in T>(T x, T y);
public static int CompareLength(string left, string right) =>
right.Length.CompareTo(left.Length);
readonly Comparison<string> _comparer = CompareLength;
list.Sort(_comparer);
However, if I omit the initial declaration of Comparison, it works fine (note - Comparison exists in the System namespace).
I assume it's an issue with my initial delegate declaration.
Enumerable.Where accepts Func<TSource, bool> delegate. If you look for documentation on Func<T,TResult> you will find out that it is declared as:
public delegate TResult Func<in T,out TResult>(T arg);
So you will need to "convert" your delegate into instance of Func<TSource, bool> which is possible either with direct creation an instance of the delegate:
new[] { 1 }.Where(new Func<int, bool>(_filterer));
Or with anonymous (lambda) function:
new[] { 1 }.Where(i => _filterer(i));
Which is actually a syntactic sugar transformed by compiler into something like this:
// generated class to hold your lambda:
[CompilerGenerated]
private sealed class <>c__DisplayClass0_0
{
public FilterInt<int> _filterer;
// your lambda:
internal bool <M>b__0(int i)
{
return _filterer(i);
}
}
// instantiation of new Func<int, bool>
Enumerable.Where(array, new Func<int, bool>(<>c__DisplayClass0_.<M>b__0));
Method group call (listInt.Where(FilterData);) also is syntactic sugar expanded by compiler into creation of new delegate:
Enumerable.Where(array, new Func<int, bool>(FilterData));
You can call like this.
Where(new Func<int, bool>(FilterInt))
Or
.Where(x => FilterInt(x))
The error occurs because of the where clause expects a Func<TSource, TResult> with a Boolean as TResult and not just a Func<int> as its representative.
IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
The closest way to use it as you wish will be something like this, but I don't believe it as a good implementation.
using System;
using System.Collections.Generic;
using System.Linq;
public delegate Func<T1, T2> FilterInt<in T1, out T2>(T1 value);
namespace DelegateTest
{
class Program
{
private static readonly List<int> List = new List<int> {0, 1, 2, 10, 11, 12};
static void Main(string[] args)
{
FilterInt<int, bool> filterInt = FilterData;
var result = List.Where(x => filterInt.Invoke(x).Invoke(x));
foreach (var item in result) Console.WriteLine(item.ToString());
}
private static Func<int, bool> FilterData(int value) => _ => value < 10;
}
}

how to implement Action<..> as Func<...>

I'd like to implement Action as func and get the error : could not use void in this context.
Please advise
Action<string> someFunc_1 = Console.WriteLine;
someFunc_1("Test");
Func<string, void> someFunc_2 = Console.WriteLine;
Action<T1, T2, ...> is done to replace Func<T1, T2, ..., void>.
You can't use void in a generic. It's not a type in C#.
Then in your case, use Action<string> instead of Func<string, void>.
Func<string, bool> someFunc_2 = s =>
{
Console.WriteLine(s);
return true;
};

Converting between Func with different # of type args

Are there built in methods for converting between the various types of Func delegates? That is, suppose you need a Func, but you have a Func (and you have the value that should be passed in for the T parameter). For example:
static TREsult Foo<TResult>(Func<TResult> f)
{
// ...
TResult result = f();
// ...
return result;
}
static int MyFunc(int i)
{
return i;
}
void CallFoo()
{
Func<int> func = ConvertFunc(MyFunc, 1); // Does this family of methods exist?
int j = Foo(func);
}
I've written my own, like this:
static Func<TResult> ConvertFunc<T, TResult>(Func<T, TResult> f1, T t)
{
return () => f1(t);
}
static Func<TResult> ConvertFunc<T1, T2, TResult>(Func<T1, T2, TResult> f2, T1 t1, T2 t2)
{
return () => f2(t1, t2);
}
// etc.
But I'm wondering if a family of methods like this exists (or even if there's a better way to do this).
Essentially, I'm doing this for a case where there is some boiler plate code in a method followed by a function call (where the number and types in the function will vary, but the return type is the same), followed by more boiler plate code.
All opinions welcome! Thanks.
static Func<TResult> ConvertFunc<T, TResult>(Func<T, TResult> f1, T t)
{
return () => f1(t);
}
This kind of code to me looks a bit dangerous - not that by itself is anything wrong but need to be careful. You are using closure to embed an input variable in the function. But this could lead to difficult bugs since if the variable changes between converting Func and running it, the result would be different.
I am just curious what would be the benefit. Are you trying to hide away input parameter from the consumer of the function? As long as the variable is a local one passed to it, would be fine.
In terms of a solution, there would not be one since .NET has created 16 different generic Func<> exactly for the same reason.
You can perhaps use reflection to implement a solution but you would be paying a penalty for calling the functions. MethodInfo.GetGenericArguments() would give you the types and you then can use MethodInfo.MakeGenericMethod() to create new ones.
Update
Just to illustrate my point:
static int Double(int number)
{
return number * 2;
}
static void Main(string[] args)
{
int i = 2;
Func<int> f = () => Double(i);
i = 3;
Console.WriteLine(f()); // prints 6 and not 4
}

How do I describe an Action<T> delegate that returns a value (non-void)?

The Action<T> delegate return void. Is there any other built-in delegate which returns non void value?
Yes. Func<> returns the type specified as the final generic type parameter, such that Func<int> returns an int and Func<int, string> accepts an integer and returns a string. Examples:
Func<int> getOne = () => 1;
Func<int, string> convertIntToString = i => i.ToString();
Action<string> printToScreen = s => Console.WriteLine(s);
// use them
printToScreen(convertIntToString(getOne()));
Sure, the Func Delegates return T.
Func<TResult> is "TResult method()"
Func<TInput, TResult> is "TResult method(TInput param)"
All the way down to
Func<T1, T2, T3, T4, TResult>
http://msdn.microsoft.com/en-us/library/bb534960.aspx
http://msdn.microsoft.com/en-us/library/bb534303.aspx
Also, for the sake of completeness, there is Predicate which returns bool.
Predicate<T> is "bool method(T param)"
http://msdn.microsoft.com/en-us/library/bfcke1bz.aspx

Categories