What is the difference between Func<string,string> and delegate? - c#

I see delegates in two forms:
A. Func<string, string> convertMethod = lambda
B. public delegate string convertMethod(string value);
I'm uncertain of what actually the difference between these two are. Are they both delegates? I believe the first one would use a lambda and the second would have to have a method to actually perform the work. I may be confused too.

First of all, your two examples are doing two totally separate things. The first is declaring a generic delegate variable and assigning a value to it, the second is just defining a delegate type. Your example, more completely, would be:
public static class Program
{
// you can define your own delegate for a nice meaningful name, but the
// generic delegates (Func, Action, Predicate) are all defined already
public delegate string ConvertedMethod(string value);
public static void Main()
{
// both work fine for taking methods, lambdas, etc.
Func<string, string> convertedMethod = s => s + ", Hello!";
ConvertedMethod convertedMethod2 = s => s + ", Hello!";
}
}
But more to the point, both Func<string,string> and delegate string convertMethod(string) would be capable of holding the same method definitions whether they be methods, anonymous methods, or lambda expressions.
As for which you should use, depends on the situation. If you want your delegate to be defined more by what it takes and returns, then the generic delegates are perfect. If you want the delegate to have some special name that gives more definition of what that delegate should do (beyond simple Action, Predicate, etc) then creating your own delegate is always an option.

The code sample you have is confusing things a bit so let me try and clear it up. The following 2 items are delegate declarations. These are easy to spot because they will always contain the delegate keyword
public delegate TReturn Func<TArg, TReturn>(Targ value);
public delegate string convertMethod(string value);
This line of code is assigning a value to a local which is typed to a delegate
Func<string, string> local = lambda;
The above code is not limited to using just lambdas though. The value could also be a compatible method group or another delegate value.
One other item to note is that even though Func<string, string> and convertMethod are both delegates with identical signatures their values are not convertible to each other. For example the following is illegal
Func<string, string> local1 = ...;
convertMethod local2 = local1; // Error!!!

From MSDN,
In versions of C# before 2.0, the only way to declare a delegate was
to use named methods. C# 2.0 introduced anonymous methods and in C#
3.0 and later, lambda expressions supersede anonymous methods as the
preferred way to write inline code.
and
There is one case in which an anonymous method provides functionality
not found in lambda expressions. Anonymous methods enable you to omit
the parameter list. This means that an anonymous method can be
converted to delegates with a variety of signatures.
You may also be interested in this SO answer on delegate keyword vs lambda expression.
Additionally, MSDN has a good article on Lambda Expressions:
delegate int del(int i);
static void Main(string[] args)
{
del myDelegate = x => x * x;
int j = myDelegate(5); //j = 25
}
In the previous example, notice that the delegate signature has one
implicitly-typed input parameter of type int, and returns an int. The
lambda expression can be converted to a delegate of that type because
it also has one input parameter (x) and a return value that the
compiler can implicitly convert to type int. (Type inference is
discussed in more detail in the following sections.) When the delegate
is invoked by using an input parameter of 5, it returns a result of
25.

A initializes an instance of a delegate (that can be called immediately). It's a variable of type Func< string, string >.
B specifies the definition of a delegate (its signature). It can be used to later define variables of type convertMethod.

Related

Why can you not use anon function with a dynamic parameter?

Just ran into this today
An anonymous function or method group cannot be used as a constituent
value of a dynamically bound operation.
when trying to do
static R ifNotNull<R>(dynamic o, Func<dynamic, R> returnFunc, R otherwise) {
return ReferenceEquals(null, o) ? otherwise : returnFunc(o);
}
and use it with
dynamic firstAddress = ...;
return ifNotNull<string>(firstAddress, (a) => a.address_1, null)
Now most of the limitations on dynamics make sense to me - you can't use an extension method because how is the compiler supposed to decide which static to compile it to? But I don't get this here. Where does the confusion come in? What exactly is the limitation?
What is the static type of the lamba a => a.address_1? You may be tempted to say it's a Func<dynamic, dynamic>. But remember:
A lambda expression is an anonymous function that you can use to
create delegates or expression tree types.
So maybe it's an Expression<Func<dynamic, dynamic>>. A lamda by itself doesn't have a single static type.
Now normally type inference would figure out that you're passing the lamba to a function that takes a Func and it will be converted to a delegate at compile time. However when you are calling with dynamic arguments the method call is dispatched dynamically.
If you have a method call with a dynamic argument, it is dispatched
dynamically, period. During the runtime binding, all the static types
of your arguments are known (emphasis mine), and types are picked for the dynamic
arguments based on their actual values.
So the fact that your method takes a Func isn't take into account, since the actual method call isn't determined until runtime so there is no type inference.
To get this to compile you'll have to cast your lamba to a Func<dynamic, string> as below:
return ifNotNull<string>(firstAddress, new Func<dynamic, string>((a) => a.address_1), null);
Now the static type of your lamda is known.
I meant that you need to cast the lambda method to the expect expression you want. Then it'll work just fine.
Like this:
return ifNotNull(firstAddress, (Func<dynamic, string>)((a) => a.address_1), null);

Can I define lambda default for some argument? [duplicate]

Is there a way to use optional arguments (default parameters) with lambda expressions in c#? I have read through the documentation but can find nothing to say one way or the other.
To illustrate, I can define simple method that uses an optional argument to supply a default value like so:
void MyMethod(string arg = "default-value")
{
Console.WriteLine(arg);
}
What I want to know is if I am able to do the same thing using a lambda expression.
// gives a syntax error
Action<string> MyMethod = (arg = "default") => Console.WriteLine(arg);
I can work in an optional parameter with a default value using a delegate, but this seems a bit clumsy.
delegate void MyDelegate(string arg = "default");
MyDelegate MyMethod = arg => Console.WriteLine(arg);
Alternatively I could check the parameter in the lambda body, something like...
Action<string> MyMethod = (arg) => Console.WriteLine(string.IsNullOrEmpty(arg) ?
"default" :
arg);
But again this seems a bit clumsy.
Is it possible to use optional parameters to set a default value in a lambda expression in c#?
No. The caller (the code invoking the delegate) doesn't "see" the lambda expression, so it doesn't make sense to specify the default parameter there. All the caller sees is the delegate. In your case, for example, the calling code only knows about Action<string> - how is the compiler meant to know to supply the default value that's specified by the lambda expression?
As an example of how things get tricky, imagine if this were viable. Then consider this code:
Action<string> action;
if (DateTime.Today.Day > 10)
{
action = (string arg = "boo") => Console.WriteLine(arg);
}
else
{
action = (string arg = "hiss") => Console.WriteLine(arg);
}
action(); // What would the compiler do here?
Bear in mind that the argument is provided by the compiler at the call site - so what should it do with the final line?
It's a bit like having an interface and an implementation - if you have a default parameter on an interface, that's fine; if you only have it on the implementation, then only callers who know the specific implementation will see it. In the case of lambda expressions, there's really no visible implementation for the caller to use: there's just the delegate signature.
The lambda will match whatever the signature of the delegate it's assigned to is; without being assigned to a delegate a lambda cannot compile.
If the delegate contains optional arguments then the use of that delegate can optionally supply arguments. If the delegate doesn't, then the use of that delegate cannot omit any arguments.
While the Action and Func delegates are very handy, and can represent most signatures, they can't represent any signature with optional arguments; you must use another delegate definition for that.
Remeber, Action and Func aren't particularly special, they're just two delegates that everyone uses so that they don't need to worry about creating their own for every little thing.

How does func ACTUALLY work

So when I return an object, under the covers I think it's returning the memory address to that object (or an object containing the memory address) which you can reference and use.
But what is actually happening when you return a func?
How does your app know which instance of an object to use with that func?
My instinct tells me that an object instance reference is passed along with the func but is that what is actually happening?
I can't seem to find much on this topic.
Edit:
To clarify, I am asking when a method returns a func
A Func is a delegate -- a type of object that is associated with a specific method signature and is usually bound to a specific method with that signature. This might be either a static or an instance method and it might be generic or not; in all cases, the delegate instance holds all the information required to call the method.
A Func is a delegate, and Delegate instances encapsulate a MethodInfo and an optional target object to invoke the method on when invoked.
Func<T> is just a delegate. If it is set to an instance method, then, it [magically] gets the correct this value when invoked. If set to a static method, then there is no this. And if it's set to a closure/lambda, the closure "captures" those variables in scope at the time of closure. lexical scope (with some caveats: things don't always work the way you think they might).
Edited to add:
From the C# standard, ISO 23270:2006 Information Technology — Programming Languages — C#, §8.10:
8.10 Delegates
Delegates enable scenarios that some other languages have addressed with function
pointers. However, unlike function pointers, delegates are object-oriented and type-safe.
A delegate declaration defines a class that is derived from the class System.Delegate.
A delegate instance encapsulates one or more methods, each of which is referred to as
a callable entity. For instance methods, a callable entity consists of an instance
and a method on that instance. For static methods, a callable entity consists of just
a method. Given a delegate instance and an appropriate set of arguments, one can invoke
all of that delegate instance’s methods with that set of arguments.
In more detail, the other standard, ISO 23271:2006 Information Technology — Common Language Infrastructure (CLI) Partitions I to VI says in §14.6:
The instance constructor (named .ctor and marked specialname and rtspecialname,
see §10.5.1) shall take exactly two parameters, the first having type System.Object,
and the second having type System.IntPtr. When actually called (via a newobj
instruction, see Partition III), the first argument shall be an instance of the class
(or one of its derived classes) that defines the target method, and the second argument
shall be a method pointer to the method to be called.
It's not that magic.
When you create an anonymous method, such as one assigned to a Func<T>, locals used inside of it are lifted into a class. Consider this:
int GetIncremented()
{
int x = 0;
Func<int> increment = () => ++x;
increment();
return x;
}
Behind the scenes, something like this will be created:
sealed class FuncData
{
public int x = 0;
public int FuncIncrement(FuncData data)
{
return ++data.x;
}
}
int GetIncremented()
{
FuncData data = new FuncData();
Func<int> increment = new Func<int>(data.FuncIncrement);
increment();
return data.x;
}
This is why out and ref parameters can't be used with anonymous methods: you can't store an out or ref as a member variable in a class.
You have both Func and Action, which are in-built delegates. The difference between these is that Func returns a type and Action does not.
You'll find Func uses heavily in the IEnumerable(T) Interface, with Linq extension methods.
Take a look at this example from the MSDN link provided...
Func<string, string> selector = str => str.ToUpper();
string[] words = { "orange", "apple", "Article", "elephant" };
IEnumerable<String> aWords = words.Select(selector);
foreach (String word in aWords)
Console.WriteLine(word);
This essentially uses the Selector Func to convert each of the strings in words to upper case.

Are method names implicitly cast to delegate types?

Im having a little trouble understanding delegates.
I have a delegate that i will invoke when a y character is entered:
public delegate void respondToY(string msgToSend);
private respondToY yHandler;
i have a subscribe method in order that calling code can ask to be notified when the delegate is invoked:
public void Subscribe(respondToY methodName)
{
yHandler += methodName;
}
As far as i can see, to register with this delegate, i need to provide something of the type respondToY. Yet when calling the subscribe method, i can supply either a new instance of the delegate or simply the name of the method. Does this mean that any method matching the delegate signature can be used and will automatically be converted to the correct delegate type?
** Edit **
So on this assumption it would also be valid to supply only a method name to things like click event handlers for buttons (provided the method took the sender, and the relevant event object), it would be converted to the required delegate?
This is a method group conversion. It converts a method group (basically the name of a method or overloaded methods) to an instance of a delegate type with a compatible signature.
Yes, any compatible method can be used. Note that you can provide a target too - for example:
string text = "Hello there";
Func<int, int, string> func = text.Substring;
Console.WriteLine(func(2, 3)); // Prints "llo", which is text.Substring(2, 3)
There must be a specific delegate type involve though. You can't just use:
Delegate x = methodName;
... the compiler doesn't know the kind of delegate to create.
For more information, see section 6.6 of the C# 4 language specification.
Note that a method group conversion always creates a new instance of the delegate in question - it isn't cached (and can't be without violating the specification.)
as far as i know ... yes, the delegate type just makes sure that the signatures match

Can I ignore delegate parameters with lambda syntax?

I am curious why C# allows me to ignore delegate parameters in some cases but not others.
For instance this is permitted:
Action<int> action = delegate { Console.WriteLine("delegate"); };
but this is not:
Action<int> action = () => Console.WriteLine("lambda");
Is there a way to initialize a delegate and ignore the parameters using a lambda? I know that I can add a single parameter to the lambda and fix the previous line but this is more of an academic question pertaining to the compiler and why or how this works.
I believe that your first sample actually creates an anonymous function that is able to take on many different signatures whose body is the single statement Console.WriteLine.... Because it can match different signatures, it does not cause a problem. In the second sample, the lambda syntax itself defines a function that takes no parameters with the same body. Obviously the latter is not consistent with the defined Action so you get the error.
C# Anonymous Method Reference
There is one case in which an
anonymous method provides
functionality not found in lambda
expressions. Anonymous methods enable
you to omit the parameter list, and
this means that an anonymous method
can be converted to delegates with a
variety of signatures. This is not
possible with lambda expressions.
To elaborate on tvanfosson's answer; this behavior is described in the C# 3.0 language specification (§7.14):
The behavior of lambda-expressions and
anonymous-method-expressions is the
same except for the following points:
• anonymous-method-expressions permit
the parameter list to be omitted
entirely, yielding convertibility to
delegate types of any list of value
parameters.
• lambda-expressions permit parameter
types to be omitted and inferred
whereas anonymous-method-expressions
require parameter types to be
explicitly stated.
• The body of a lambda-expression can
be an expression or a statement block
whereas the body of an
anonymous-method-expression must be a
statement block.
• Since only lambda-expressions can
have an expression body, no
anonymous-method-expression can be
successfully converted to an
expression tree type (§4.6).
I think:
Action<int> action = () => Console.WriteLine("lambda");
is the equivalent of:
Action<int> action = delegate() { Console.WriteLine("delegate"); };
which wouldn't compile either. As Daniel Plaisted says () is explicitly saying there aren't any parameters.
If there were an equivalent of delegate{} it might be:
Action<int> action = => Console.WriteLine("lambda")
Which isn't very pretty and I suspect it suspect isn't in the spirit of lambda expressions.
As others said, no, you can't skip declaring the parameters to a lambda. But, for cleanliness, I suggest giving them a name such as _. For example
foo.Click += (_,__) => { ... }
You aren't ignoring them per-se, but you're indicating you don't care what they are and will not use them.
The () => ... syntax explicitly specifies that the lambda takes no parameters. Perhaps the language could be modified so that () => really meant "Infer the parameters of this lambda for me" in the same way the delegate syntax does, but that would make the language more complicated. When designing new language features, you start at minus 100, and I don't think this one passes the test.
There may also be more technical reasons why this would be difficult to implement (which is probably more in line with what you were asking for, but I doubt the technical reasons drove this decision if it ever came up).
I'd say it's to have a forced use of the parameters of the lambda expression.
Take your first example, how would you interact with the passed in value, there's no local representation of it.
What about this?
Func<int> lamdapointer = () => TwoArgMethodThatReturnsInt(10,20); // the same method cannot be called with the delegate "NoArgmethodThatReturnsInt"
lamdapointer();
Delegate int NoArgmethodThatReturnsInt();
NoArgmethodThatReturnsInt del = NoArgmethodThatReturnsInt; // only this is possible with delegates
public int TwoArgMethodThatReturnsInt(int x,int y)
{
return x + y;
}
public int NoArgmethodThatReturnsInt()
{
return 20;
}
Actually, delegate {} does not specify any parameters and fits any delegate method signature - therefore it is permitted in your first construcion.
The Lambda expression () => ...; specifically states parameterless delegate, which contradicts the signature required by Action - a delegate with single parameter.
You may want to use one of the following options.
If you need the action to have a parameter, you can do it the next way ("_" is a legal character for identifier name).
Action<int> action = _ => Console.WriteLine("lambda");
Or you may want to use parameterless Action as follows:
Action action = () => Console.WriteLine("lambda");

Categories

Resources