I know how to use Action and Func in .NET, but every single time I start to, the exact same solution can be achieved with a regular old Method that I call instead.
This excludes when an Action or Func is used as an argument for something I don't control, like LINQ's .Where.
So basically my question is...why do these exist? What do they give me extra and new that a simple Method doesn't?
I think other answers here talk about what an Action/Func is and its use. I will try to answer how to choose between Action/Func and method. The differences first:
1) From a raw performance point of view, delegates are slower compared to direct method calls, but it's so insignificant that worrying about it is a bad practice.
2) Methods can have overloads (same function names with different signatures) but not Action/Func delegates since they are declared as variables and by C# rules you cant have two variables with the same name in a given scope.
bool IsIt() { return 1 > 2; }
bool IsIt(int i) { return i > 2; } //legal
Func<bool> IsIt = () => 1 > 2;
Func<int, bool> IsIt = i => i > 2; //illegal, duplicate variable naming
3) Consequently, Action/Func are reassignable and can point to any function, while methods once compiled remain to be the same forever. It is semantically wrong to use Func/Action if the method it points to never changes during run time.
bool IsIt() { return 1 > 2; } //always returns false
Func<bool> IsIt = () => 1 > 2;
IsIt = () => 2 > 1; //output of IsIt depends on the function it points to.
4) You can specify ref/out parameters for normal methods. For eg, you can have
bool IsIt(out string p1, ref int p2) { return 1 > 2; } //legal
Func<out string, ref int, bool> IsIt; //illegal
5) You cannot introduce new generic type parameter for Action/Func (they are generic already btw, but the type arguments can only be a known type or types specified in the parent method or class), unlike methods.
bool IsIt<A, R>() { return 1 > 2; } //legal
Func<bool> IsIt<A, R> = () => 1 > 2; //illegal
6) Methods can have optional parameters, not Action/Func.
bool IsIt(string p1 = "xyz") { return 1 > 2; } //legal
Func<string, bool> IsIt = (p1 = "xyz") => 1 > 2; //illegal
7) You can have params keyword for parameters of a method, not so with Action/Func.
bool IsIt(params string[] p1) { return 1 > 2; } //legal
Func<params string[], bool> IsIt = p1 => 1 > 2; //illegal
8) Intellisense plays well with parameter names of methods (and accordingly you have cool XML documentation available for methods), not so with Action/Func. So as far as readability is concerned, regular methods win.
9) Action/Func have a parameter limit of 16 (not that you can't define your own ones with more) but methods support more than you will ever need.
As to when to use which, I would consider the following:
When you are forced to use one based on any of the above points, then you anyway have no other choice. Point 3 is the most compelling I find upon which you will have to base your decision.
In most normal cases, a regular method is the way to go. It's the standard way of refactoring a set of common functionality in C# and VB.NET world.
As a rule of thumb, if the function is more than a line, I prefer a method.
If the function has no relevance outside a specific method and the function is too trivial, like a simple selector (Func<S, T>) or a predicate (Func<bool>) I would prefer Action/Func. For eg,
public static string GetTimeStamp()
{
Func<DateTime, string> f = dt => humanReadable
? dt.ToShortTimeString()
: dt.ToLongTimeString();
return f(DateTime.Now);
}
There could be situations where Action/Func makes more sense. For instance if you have to build a heavy expression and compile a delegate, its worth doing it only once and caching the compiled delegate.
public static class Cache<T>
{
public static readonly Func<T> Get = GetImpl();
static Func<T> GetImpl()
{
//some expensive operation here, and return a compiled delegate
}
}
instead of
public static class Cache<T>
{
public static T Get()
{
//build expression, compile delegate and invoke the delegate
}
}
In the first case when you call Get, GetImpl is executed only once, where as in the second case, (expensive) Get will be called every time.
Not to forget anonymous method itself will have certain limits unrelated to Func/Action, making the use little different. Also see this for a related question.
Action and Func are framework-provided Delegate types. Delegates allow functions to be treated like variables, meaning that you can (among other things) pass them from method to method. If you have ever programmed in C++, you can think of Delegates as function pointers that are restricted by the signature of the method they refer to.
Action and Func specifically are generic delegates (meaning they take type parameters) with some of the most common signatures- almost any method in most programs can be represented using one or the other of those two, saving people a lot of time manually defining delegates like we did in .net prior to version 2. In fact, when I see code like this in a project, I can usually safely assume that the project was migrated from .net 1.1:
// This defines a delegate (a type that represents a function)
// but usages could easily be replaced with System.Action<String>
delegate void SomeApplicationSpecificName(String someArgument);
I'd recommend that you look into delegates some more. They are a hugely powerful feature of the C# language.
I use them to create an array of functions. For instance, I may have a ComboBox full of actions that could be taken. I populate the ComboBox with items of a class or structure:
public class ComboBoxAction
{
private string text;
private Action method;
public ComboBoxAction(string text, Action method)
{
this.text = text;
this.method = method;
}
public override string ToString()
{
return this.text;
}
public void Go()
{
this.method();
}
}
Then when someone selects an item, I can call the action.
CType(ComboBox1.SelectedItem, ComboBoxAction).Go()
This is far easier than having a Select statement determine which method to call based on the ComboBox's text.
There's plenty of cases where a Func can help where a Method wouldn't.
public void DoThing(MyClass foo, Func<MyClass, string> func)
{
foo.DoSomething;
var result = func(foo);
foo.DoStringThing(result);
}
So you can specify a different Func whenever you call this method - the DoThing method doesn't need to know what's being done, just that whatever it is will return a string.
You can do this without using the Func keyword by using the delegate keyword instead; it works much the same way.
One great use of action and func are when we need to perform some operation (before or after a method), irrespective of what the method is. For example, we need to retry the method 10 times if exception occurs.
Consider the following method – its return type is generic. So it can be applied on func with any return type.
public static T ExecuteMultipleAttempts<T>(Func<T> inputMethod, Action additionalTask, int wait, int numOfTimes)
{
var funcResult = default(T);
int counter = 0;
while (counter < numOfTimes)
{
try
{
counter++;
funcResult = inputMethod();
//If no exception so far, the next line will break the loop.
break;
}
catch (Exception ex)
{
if (counter >= numOfTimes)
{
//If already exceeded the number of attemps, throw exception
throw;
}
else
{
Thread.Sleep(wait);
}
if (additionalTask != null)
{
additionalTask();
}
}
}
return funcResult;
}
Related
Want feedback if i`m correct here?
Use void if you are not returning anything in a method,
otherwise
Name your data types used in the method criteria before method name.
use Return in the method before the calculation or output.
So something like this.
static int MyMethod(int x)
{
return 5 + x;
}
static void Main(string[] args)
{
Console.WriteLine(MyMethod(3));
}
// Outputs 8 (5 + 3)
What if my method has ints and doubles?
Do I write as follows? (another words do I have to mention every type i`m using prior to the method name?
static int double myMethod (int x, double y)
Even with that I dont know when is a method void? It seems my methods all return values.
Isnt the following returning the values of the arguments? So why should I label it void?
static void MyMethod(string fname, int age)
{
Console.WriteLine(fname + " is " + age);
}
static void Main(string[] args)
{
MyMethod("Liam", 20);
MyMethod("Jenny", 25);
MyMethod("Tom", 31);
}
I can only think that a void means there is no new calculation being done in the actual method body, passing arguments into a method and spitting them out for user viewing does not mean its "returning a value", I dont know what i`m talking about.
Let's be completely clear about what these bullets mean.
Use void if you are not returning anything in a method, otherwise
In this context, "return" means that the method provides an output that can be assigned to a variable by the caller. For example
int Return10()
{
return 10;
}
...allows the caller to do this:
int x = Return10();
Console.WriteLine(x); //Outputs "10"
A method should "return" void when its results cannot be assigned. For example, if the results are printed on the screen.
void Print10()
{
Console.WriteLine("10"); //Prints 10 to the screen
}
...which allows the caller to do this:
Print10();
You cannot assign it because it doesn't return anything. This doesn't work:
int x = Print10(); //Compiler error
Name your data types used in the method criteria before method name.
A method can return exactly one value or object. So "types" here is wrong. You can only specify one type.
Use return in the method before the calculation or output.
This is a little misleading. The return keyword should be followed by an expression which can be assigned.
int Return10()
{
return 10 + 10; //Is okay because it's an expression and could be assigned
}
int Return10()
{
var x = 10 + 10;
return x; //This is also okay; in fact it does exactly the same thing as the previous example
}
int Return10()
{
return Console.WriteLine("10"); //Compiler error; can't be assigned to anything.
}
By the way, a method can also output something and return it:
int WriteAndReturn10()
{
int x = 10;
Console.WriteLine(x);
return x;
}
I am going to address the following
What if my method has ints and doubles? Do I write as follows?
(another words do I have to mention every type i`m using prior to the
method name?
There are no built in ways or syntax to return more than one type from a method as the return parameter.. This is basically historical and has been this way since dinosaurs roamed the earth.
However, there are lots of options that achieve the same result. For instance, you could use a custom struct, you could use out parameters, you could use a class, or a delegate parameter of some kind. However, a modern succinct approach might be to use a Value Tuple:
static (int someInt, double someDouble) myMethod (int x, double y)
{
return (x,y);
}
Fun Fact : even though this looks like you a returning more than one type, you are actually just invoking a special syntax that wraps your return parameters in a single type of struct
Usage
var result = myMethod(1,2.2);
Console.WriteLine(result.someInt);
Console.WriteLine(result.someDouble);
Or if you want to get fancy, you can use the newer deconstructed syntax
var (someInt, someDouble) = myMethod(1,2.2);
Console.WriteLine(someInt);
Console.WriteLine(someDouble);
Additional Resources
return (C# Reference)
Methods (C# Programming Guide)
Tuple types (C# reference)
out parameter modifier (C# Reference)
ref (C# Reference)
Using Delegates (C# Programming Guide)
What is a closure? Do we have them in .NET?
If they do exist in .NET, could you please provide a code snippet (preferably in C#) explaining it?
I have an article on this very topic. (It has lots of examples.)
In essence, a closure is a block of code which can be executed at a later time, but which maintains the environment in which it was first created - i.e. it can still use the local variables etc of the method which created it, even after that method has finished executing.
The general feature of closures is implemented in C# by anonymous methods and lambda expressions.
Here's an example using an anonymous method:
using System;
class Test
{
static void Main()
{
Action action = CreateAction();
action();
action();
}
static Action CreateAction()
{
int counter = 0;
return delegate
{
// Yes, it could be done in one statement;
// but it is clearer like this.
counter++;
Console.WriteLine("counter={0}", counter);
};
}
}
Output:
counter=1
counter=2
Here we can see that the action returned by CreateAction still has access to the counter variable, and can indeed increment it, even though CreateAction itself has finished.
If you are interested in seeing how C# implements Closure read "I know the answer (its 42) blog"
The compiler generates a class in the background to encapsulate the anoymous method and the variable j
[CompilerGenerated]
private sealed class <>c__DisplayClass2
{
public <>c__DisplayClass2();
public void <fillFunc>b__0()
{
Console.Write("{0} ", this.j);
}
public int j;
}
for the function:
static void fillFunc(int count) {
for (int i = 0; i < count; i++)
{
int j = i;
funcArr[i] = delegate()
{
Console.Write("{0} ", j);
};
}
}
Turning it into:
private static void fillFunc(int count)
{
for (int i = 0; i < count; i++)
{
Program.<>c__DisplayClass1 class1 = new Program.<>c__DisplayClass1();
class1.j = i;
Program.funcArr[i] = new Func(class1.<fillFunc>b__0);
}
}
Closures are functional values that hold onto variable values from their original scope. C# can use them in the form of anonymous delegates.
For a very simple example, take this C# code:
delegate int testDel();
static void Main(string[] args)
{
int foo = 4;
testDel myClosure = delegate()
{
return foo;
};
int bar = myClosure();
}
At the end of it, bar will be set to 4, and the myClosure delegate can be passed around to be used elsewhere in the program.
Closures can be used for a lot of useful things, like delayed execution or to simplify interfaces - LINQ is mainly built using closures. The most immediate way it comes in handy for most developers is adding event handlers to dynamically created controls - you can use closures to add behavior when the control is instantiated, rather than storing data elsewhere.
Func<int, int> GetMultiplier(int a)
{
return delegate(int b) { return a * b; } ;
}
//...
var fn2 = GetMultiplier(2);
var fn3 = GetMultiplier(3);
Console.WriteLine(fn2(2)); //outputs 4
Console.WriteLine(fn2(3)); //outputs 6
Console.WriteLine(fn3(2)); //outputs 6
Console.WriteLine(fn3(3)); //outputs 9
A closure is an anonymous function passed outside of the function in which it is created.
It maintains any variables from the function in which it is created that it uses.
A closure is when a function is defined inside another function (or method) and it uses the variables from the parent method. This use of variables which are located in a method and wrapped in a function defined within it, is called a closure.
Mark Seemann has some interesting examples of closures in his blog post where he does a parallel between oop and functional programming.
And to make it more detailed
var workingDirectory = new DirectoryInfo(Environment.CurrentDirectory);//when this variable
Func<int, string> read = id =>
{
var path = Path.Combine(workingDirectory.FullName, id + ".txt");//is used inside this function
return File.ReadAllText(path);
};//the entire process is called a closure.
Here is a contrived example for C# which I created from similar code in JavaScript:
public delegate T Iterator<T>() where T : class;
public Iterator<T> CreateIterator<T>(IList<T> x) where T : class
{
var i = 0;
return delegate { return (i < x.Count) ? x[i++] : null; };
}
So, here is some code that shows how to use the above code...
var iterator = CreateIterator(new string[3] { "Foo", "Bar", "Baz"});
// So, although CreateIterator() has been called and returned, the variable
// "i" within CreateIterator() will live on because of a closure created
// within that method, so that every time the anonymous delegate returned
// from it is called (by calling iterator()) it's value will increment.
string currentString;
currentString = iterator(); // currentString is now "Foo"
currentString = iterator(); // currentString is now "Bar"
currentString = iterator(); // currentString is now "Baz"
currentString = iterator(); // currentString is now null
Hope that is somewhat helpful.
Closures are chunks of code that reference a variable outside themselves, (from below them on the stack), that might be called or executed later, (like when an event or delegate is defined, and could get called at some indefinite future point in time)... Because the outside variable that the chunk of code references may gone out of scope (and would otherwise have been lost), the fact that it is referenced by the chunk of code (called a closure) tells the runtime to "hold" that variable in scope until it is no longer needed by the closure chunk of code...
Basically closure is a block of code that you can pass as an argument to a function. C# supports closures in form of anonymous delegates.
Here is a simple example:
List.Find method can accept and execute piece of code (closure) to find list's item.
// Passing a block of code as a function argument
List<int> ints = new List<int> {1, 2, 3};
ints.Find(delegate(int value) { return value == 1; });
Using C#3.0 syntax we can write this as:
ints.Find(value => value == 1);
If you write an inline anonymous method (C#2) or (preferably) a Lambda expression (C#3+), an actual method is still being created. If that code is using an outer-scope local variable - you still need to pass that variable to the method somehow.
e.g. take this Linq Where clause (which is a simple extension method which passes a lambda expression):
var i = 0;
var items = new List<string>
{
"Hello","World"
};
var filtered = items.Where(x =>
// this is a predicate, i.e. a Func<T, bool> written as a lambda expression
// which is still a method actually being created for you in compile time
{
i++;
return true;
});
if you want to use i in that lambda expression, you have to pass it to that created method.
So the first question that arises is: should it be passed by value or reference?
Pass by reference is (I guess) more preferable as you get read/write access to that variable (and this is what C# does; I guess the team in Microsoft weighed the pros and cons and went with by-reference; According to Jon Skeet's article, Java went with by-value).
But then another question arises: Where to allocate that i?
Should it actually/naturally be allocated on the stack?
Well, if you allocate it on the stack and pass it by reference, there can be situations where it outlives it's own stack frame. Take this example:
static void Main(string[] args)
{
Outlive();
var list = whereItems.ToList();
Console.ReadLine();
}
static IEnumerable<string> whereItems;
static void Outlive()
{
var i = 0;
var items = new List<string>
{
"Hello","World"
};
whereItems = items.Where(x =>
{
i++;
Console.WriteLine(i);
return true;
});
}
The lambda expression (in the Where clause) again creates a method which refers to an i. If i is allocated on the stack of Outlive, then by the time you enumerate the whereItems, the i used in the generated method will point to the i of Outlive, i.e. to a place in the stack that is no longer accessible.
Ok, so we need it on the heap then.
So what the C# compiler does to support this inline anonymous/lambda, is use what is called "Closures": It creates a class on the Heap called (rather poorly) DisplayClass which has a field containing the i, and the Function that actually uses it.
Something that would be equivalent to this (you can see the IL generated using ILSpy or ILDASM):
class <>c_DisplayClass1
{
public int i;
public bool <GetFunc>b__0()
{
this.i++;
Console.WriteLine(i);
return true;
}
}
It instantiates that class in your local scope, and replaces any code relating to i or the lambda expression with that closure instance. So - anytime you are using the i in your "local scope" code where i was defined, you are actually using that DisplayClass instance field.
So if I would change the "local" i in the main method, it will actually change _DisplayClass.i ;
i.e.
var i = 0;
var items = new List<string>
{
"Hello","World"
};
var filtered = items.Where(x =>
{
i++;
return true;
});
filtered.ToList(); // will enumerate filtered, i = 2
i = 10; // i will be overwriten with 10
filtered.ToList(); // will enumerate filtered again, i = 12
Console.WriteLine(i); // should print out 12
it will print out 12, as "i = 10" goes to that dispalyclass field and changes it just before the 2nd enumeration.
A good source on the topic is this Bart De Smet Pluralsight module (requires registration) (also ignore his erroneous use of the term "Hoisting" - what (I think) he means is that the local variable (i.e. i) is changed to refer to the the new DisplayClass field).
In other news, there seems to be some misconception that "Closures" are related to loops - as I understand "Closures" are NOT a concept related to loops, but rather to anonymous methods / lambda expressions use of local scoped variables - although some trick questions use loops to demonstrate it.
A closure aims to simplify functional thinking, and it allows the runtime to manage
state, releasing extra complexity for the developer. A closure is a first-class function
with free variables that are bound in the lexical environment. Behind these buzzwords
hides a simple concept: closures are a more convenient way to give functions access
to local state and to pass data into background operations. They are special functions
that carry an implicit binding to all the nonlocal variables (also called free variables or
up-values) referenced. Moreover, a closure allows a function to access one or more nonlocal variables even when invoked outside its immediate lexical scope, and the body
of this special function can transport these free variables as a single entity, defined in
its enclosing scope. More importantly, a closure encapsulates behavior and passes it
around like any other object, granting access to the context in which the closure was
created, reading, and updating these values.
Just out of the blue,a simple and more understanding answer from the book C# 7.0 nutshell.
Pre-requisit you should know :A lambda expression can reference the local variables and parameters of the method
in which it’s defined (outer variables).
static void Main()
{
int factor = 2;
//Here factor is the variable that takes part in lambda expression.
Func<int, int> multiplier = n => n * factor;
Console.WriteLine (multiplier (3)); // 6
}
Real part:Outer variables referenced by a lambda expression are called captured variables. A lambda expression that captures variables is called a closure.
Last Point to be noted:Captured variables are evaluated when the delegate is actually invoked, not when the variables were captured:
int factor = 2;
Func<int, int> multiplier = n => n * factor;
factor = 10;
Console.WriteLine (multiplier (3)); // 30
A closure is a function, defined within a function, that can access the local variables of it as well as its parent.
public string GetByName(string name)
{
List<things> theThings = new List<things>();
return theThings.Find<things>(t => t.Name == name)[0];
}
so the function inside the find method.
t => t.Name == name
can access the variables inside its scope, t, and the variable name which is in its parents scope. Even though it is executed by the find method as a delegate, from another scope all together.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
To explain the matter here is some Scala code:
object Scratch {
def foo: Int = {
val list = List(1, 2, 3, 4)
list.foreach { each =>
if(each > 2) {
return each
}
println(each)
}
return 5
}
def main(args : Array[String]) : Unit = {
val i = foo
println("i: " + i)
}
The code above prints this to the console:
1
2
i: 3
In particular, note that the closure used by list.foreach has a return statement, and this return statement causes foo, the caller of list.foreach, to return, interrupting the foreach enumeration and providing the actual return value for foo. This return is not declared within the foo method itself, and so is a "non-local return".
The question is now how the same thing would turn out in C#, e.g. will something else be printed to the console? The question is about non-local returns in C# from inside closures. Only if they are supported the same output would occur as in the code above.
Note: This is no speciality of Scala. Other language have this as well like Smalltalk or Kotlin, probably also Ruby and others for sure.
I wanted to try this out myself, but after downloadinng 9 GB for installing Visual Studio 2017 I was told to upgrade to Windows 10 and that was not what I wanted to do just to get this question answered.
No, C# does not support non-local returns in closures. A C# closure is a method unto itself, and does not share context (other than captured variables) with its enclosing method. When you return from within a lambda expression, you are returning from that method, i.e. the anonymous method the lambda refers to. It doesn't affect the method in which the lambda is declared, nor the method from which the lambda is invoked (if different from that in which it's declared).
I'm not that familiar with either Scala or Ruby, but it appears that Scala is more similar to Ruby than to C#. If so, I take it that non-local returns cause the calling method to return. It just happens in your example that the calling method is the same as the declaring method, but for obvious reasons it would be pretty odd for a lambda to cause the declaring method to return. I.e. the lambda might be invoked after the declaring method has already returned. There's more in-depth discussion of Ruby (and by inference, Scala) at the Stack Overflow question Is Ruby's code block same as C#'s lambda expression?.
Of course, you can still accomplish the same effect in C#. It's just that the exact syntax you're using won't do that. In .NET, the List<T> generic class has a ForEach() method, so taking your code example literally (i.e. using that built-in ForEach() method), this is the closest you can come in C#:
static void Main(string[] args)
{
var i = foo();
WriteLine($"i: {i}");
}
static int foo()
{
var list = new List<int> { 1, 2, 3, 4 };
try
{
list.ForEach(each =>
{
if (each > 2)
{
throw new LocalReturnException(each);
}
WriteLine(each);
});
}
catch (LocalReturnException e)
{
return e.Value;
}
return 5;
}
class LocalReturnException : Exception
{
public int Value { get; }
public LocalReturnException(int value)
{
Value = value;
}
}
Because the List<T>.ForEach() method does not provide any mechanism to interrupt its enumeration of the source enumerable, the only way to get the method to return prematurely is to bypass the normal method-returning mechanisms by throwing an exception.
Of course, exceptions are fairly heavy-weight. There's a marginal cost just for the try/catch handler, and actually throwing and catching one is very costly. If you have a need for this idiom, it would be better to create your own enumeration method which provides for a mechanism to interrupt the enumeration and return a value. For example, create extension methods like so:
public static T? InterruptableForEach<T>(this IEnumerable<T> source, Func<T, T?> action)
where T : struct
{
foreach (T t in source)
{
T? result = action(t);
if (result != null) return result;
}
return null;
}
public static T InterruptableForEach<T>(this IEnumerable<T> source, Func<T, T> action)
where T : class
{
foreach (T t in source)
{
T result = action(t);
if (result != null) return result;
}
return null;
}
The first is needed for your example. I show two, because C# treats value types like int differently from reference types when it comes to null values, but the second isn't strictly needed here.
With the extension method, you can then do something like this:
static int foo()
{
var list = new List<int> { 1, 2, 3, 4 };
var result = list.InterruptableForEach(each =>
{
if (each > 2)
{
return each;
}
WriteLine(each);
return null;
});
return result ?? 5;
}
Note that the caller needs to cooperate with the lambda and the extension method. That is, the extension method is explicitly reporting what the lambda itself returned, so that it knows whether the lambda returned prematurely and if so, what the value is.
On the one hand, this is a bit more clumsy and verbose than the Scala version. On the other hand, it's consistent with C#'s tendency toward explicitness and expressiveness, and avoidance of ambiguous situations (such as, what if the foo() method didn't return an int, but the lambda did?).
This answer shows yet another possible approach. I personally would prefer either of the above, as they both actually interrupt the enumeration, rather than just skip the main lambda body until the end of the enumeration (which could be a problem for infinite enumerations), and don't introduce the additional captured variables required by that answer. But it does work in your example.
this are my answers to your questions:
1)
You dont need to install anything for playing arround with C# and LINQ. You can simply use https://dotnetfiddle.net
2) Here is my code https://dotnetfiddle.net/3V8vBj
using System.Collections.Generic;
public class Program
{
static int foo()
{
var list = new List<int> { 1, 2, 3, 4 };
int ret = 5;
bool keepGoing = true;
list.ForEach(each =>
{
if (!keepGoing)
return;
if (each>2)
{
ret=each;
keepGoing = false;
return;
}
System.Console.WriteLine(each);
});
return ret;
}
public static void Main(string[] args)
{
var i = foo();
System.Console.WriteLine("i: " + i);
}
}
3) When you using LINQ Foreach you can not simply break it for return, since it is a delegate function. So I had to implement keepGoing.
4) The nested delegate function can not return a value, so I have to use "ret" for setting the return inside the LINQ Foreach.
I hope this answers your question, but I am not really sure that I understand it right.
I am used to using functions that return a single value "in-line" like so:
Label1.Text = firstString + functionReturnSecondString(aGivenParameter);
Can this be done for a function that returns two values?
Hypothetical example:
label1.Text = multipleReturnFunction(parameter).firstValue
I have been looking into returning more than one value and it looks like the best options are using a tuple, struct, or an array list.
I made a working function that retuns a struct. However the way I got it to work I need to first call the function, then I can use the values. It doesn't seem possible to make it happen all on the same line without writing another function.
multipleReturnFunction(parameter);
Label1.Text = firstString + classOfStruct.secondString;
I haven't made a function that returns a tuple or array list yet, so I'm not sure. Is it possible to call those functions and reference the return values "inline"?
I appreciate your feedback.
I have a grotty hack for exactly this type of scenario - when you want to perform multiple operations on the return value without defining an extra variable to store it:
public static TResult Apply<TInput, TResult>(this TInput input, Func<TInput, TResult> transformation)
{
return transformation(input);
}
... and here's the reason it came about in the first place:
var collection = Enumerable.Range(1, 3);
// Average reimplemented with Aggregate.
double average = collection
.Aggregate(
new { Count = 0, Sum = 0 },
(acc, i) => new { Count = acc.Count + 1, Sum = acc.Sum + i })
.Apply(a => (double)a.Sum / (double)a.Count); // Note: we have access to both Sum and Count despite never having stored the result of the call to .Aggregate().
Console.WriteLine("Average: {0}", average);
Needless to say this is better suited for academic exercises than actual production code.
Alternatively, use the ref or they out keyword.
Example:
int a = 0, b = 0;
void DoSomething(ref int a, ref int b) {
a = 1;
b = 2;
}
Console.WriteLine(a); // Prints 1
Console.WriteLine(b); // Prints 2
It's not inline and I personally would consider a class or a struct before using the ref or the out keyword. Let's consider the theory: when you want to return multiple things, you have in fact an object that has multiple properties which you want to make available to the caller of your function.
Therefore it is much more correct to actually create an object (either by using a class or a struct) that represents what you want to make available and returning that.
The only time I use the ref or the out keyword is when using DLL imports because those functions often have pointers as their calling arguments and I personally don't see any benefit in using them in your typical normal application.
To do this inline, I think you would have to have another method that takes your struct and gives you the string you are looking for.
public string NewMethod(object yourStruct)
{
return string.Format("{0} {1}", yourStruct.value1, yourStruct.value2);
}
Then in the page, you do this:
Label1.Text = NewMethod(multipleReturnFunction(parameter));
C# doesn't have Inline functions, but it does support anonymous functions which can be closures.
With these techniques, you can say:
var firstString=default(String);
var secondString=default(String);
((Action<String>)(arg => {
firstString="abc"+arg;
secondString="xyz";
}))("wtf");
label1.Text=firstString+secondString;
Debug.Print("{0}", label1.Text);
((Action<String>)(arg => {
firstString="123"+arg;
secondString="456";
}))("???");
label1.Text=firstString+secondString;
Debug.Print("{0}", label1.Text);
or name the delegate and reuse it:
var firstString=default(String);
var secondString=default(String);
Action<String> m=
arg => {
firstString="abc"+arg;
secondString="xyz";
};
m("wtf");
label1.Text=firstString+secondString;
Debug.Print("{0}", label1.Text);
m("???");
label1.Text=firstString+secondString;
Debug.Print("{0}", label1.Text);
So, do you really need a method returns multiple values?
Each method can return only one value. Thats how methods defined in .NET
Methods are declared in a class or struct by specifying the access
level such as public or private, optional modifiers such as abstract
or sealed, the return value, the name of the method, and any method
parameters
If you need to return more than one value from method, then you have three options:
Return complex type which will hold all values. That cannot help you in this case, because you will need local variable to store value returned by method.
Use out parameters. Also not your case - you will need to declare parameters before method call.
Create another method, which does all work and returns single value.
Third option looks like
Label1.Text = AnotherMethod(parameters);
And implementation
public string AnotherMethod(parameters)
{
// use option 1 or 2 to get both values
// return combined string which uses both values and parameters
}
BTW One more option - do not return values at all - you can use method which sets several class fields.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
What are your usage of delegates in C#?
Now that we have lambda expressions and anonymous methods in C#, I use delegates much more. In C# 1, where you always had to have a separate method to implement the logic, using a delegate often didn't make sense. These days I use delegates for:
Event handlers (for GUI and more)
Starting threads
Callbacks (e.g. for async APIs)
LINQ and similar (List.Find etc)
Anywhere else where I want to effectively apply "template" code with some specialized logic inside (where the delegate provides the specialization)
Delegates are very useful for many purposes.
One such purpose is to use them for filtering sequences of data. In this instance you would use a predicate delegate which accepts one argument and returns true or false depending on the implementation of the delegate itself.
Here is a silly example - I am sure you can extrapolate something more useful out of this:
using System;
using System.Linq;
using System.Collections.Generic;
class Program
{
static void Main()
{
List<String> names = new List<String>
{
"Nicole Hare",
"Michael Hare",
"Joe Hare",
"Sammy Hare",
"George Washington",
};
// Here I am passing "inMyFamily" to the "Where" extension method
// on my List<String>. The C# compiler automatically creates
// a delegate instance for me.
IEnumerable<String> myFamily = names.Where(inMyFamily);
foreach (String name in myFamily)
Console.WriteLine(name);
}
static Boolean inMyFamily(String name)
{
return name.EndsWith("Hare");
}
}
Found another interesting answer:
A coworker just asked me this question - what's the point of delegates in .NET? My answer was very short and one that he had not found online: to delay execution of a method.
Source: LosTechies
Just like LINQ is doing.
Delegates can often be used in place of an interface with one method, a common example of this would be the observer pattern. In other languages if you want to receive a notification that something has happened you might define something like:
class IObserver{ void Notify(...); }
In C# this is more commonly expressed using events, where the handler is a delegate, for example:
myObject.SomeEvent += delegate{ Console.WriteLine("..."); };
Another great place to use delegates if when you have to pass a predicate into a function, for example when selecting a set of items from a list:
myList.Where(i => i > 10);
The above is an example of the lambda syntax, which could also have been written as follows:
myList.Where(delegate(int i){ return i > 10; });
Another place where it can be useful to use delegates is to register factory functions, for example:
myFactory.RegisterFactory(Widgets.Foo, () => new FooWidget());
var widget = myFactory.BuildWidget(Widgets.Foo);
I hope this helps!
You can use delegates to declare function-typed variables and parameters.
Example
Consider the "resource borrowing" pattern. You want to control the creation and cleanup of a resource, while allowing client code to "borrow" the resource in between.
This declares a delegate type.
public delegate void DataReaderUser( System.Data.IDataReader dataReader );
Any method matching this signature can be used to instantiate a delegate of this type. In C# 2.0, this can be done implicitly, simply by using method's name, as well as by using anonymous methods.
This method uses the type as a parameter. Note the delegate's invocation.
public class DataProvider
{
protected string _connectionString;
public DataProvider( string psConnectionString )
{
_connectionString = psConnectionString;
}
public void UseReader( string psSELECT, DataReaderUser readerUser )
{
using ( SqlConnection connection = new SqlConnection( _connectionString ) )
try
{
SqlCommand command = new SqlCommand( psSELECT, connection );
connection.Open();
SqlDataReader reader = command.ExecuteReader();
while ( reader.Read() )
readerUser( reader ); // the delegate is invoked
}
catch ( System.Exception ex )
{
// handle exception
throw ex;
}
}
}
The function can be called with an anonymous method as follows. Note that the anonymous method can use variables declared outside of itself. This is extremely handy (although the example is a little contrived).
string sTableName = "test";
string sQuery = "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='" + sTableName + "'";
DataProvider.UseReader( sQuery,
delegate( System.Data.IDataReader reader )
{
Console.WriteLine( sTableName + "." + reader[0] );
} );
I'm coming in on this really late but I was having trouble figuring out the purpose of delegates today and wrote two simple programs that give the same output that I think explains their purpose well.
NoDelegates.cs
using System;
public class Test {
public const int MAX_VALUE = 255;
public const int MIN_VALUE = 10;
public static void checkInt(int a) {
Console.Write("checkInt result of {0}: ", a);
if (a < MAX_VALUE && a > MIN_VALUE)
Console.WriteLine("max and min value is valid");
else
Console.WriteLine("max and min value is not valid");
}
public static void checkMax(int a) {
Console.Write("checkMax result of {0}: ", a);
if (a < MAX_VALUE)
Console.WriteLine("max value is valid");
else
Console.WriteLine("max value is not valid");
}
public static void checkMin(int a) {
Console.Write("checkMin result of {0}: ", a);
if (a > MIN_VALUE)
Console.WriteLine("min value is valid");
else
Console.WriteLine("min value is not valid");
Console.WriteLine("");
}
}
public class Driver {
public static void Main(string [] args) {
Test.checkInt(1);
Test.checkMax(1);
Test.checkMin(1);
Test.checkInt(10);
Test.checkMax(10);
Test.checkMin(10);
Test.checkInt(20);
Test.checkMax(20);
Test.checkMin(20);
Test.checkInt(30);
Test.checkMax(30);
Test.checkMin(30);
Test.checkInt(254);
Test.checkMax(254);
Test.checkMin(254);
Test.checkInt(255);
Test.checkMax(255);
Test.checkMin(255);
Test.checkInt(256);
Test.checkMax(256);
Test.checkMin(256);
}
}
Delegates.cs
using System;
public delegate void Valid(int a);
public class Test {
public const int MAX_VALUE = 255;
public const int MIN_VALUE = 10;
public static void checkInt(int a) {
Console.Write("checkInt result of {0}: ", a);
if (a < MAX_VALUE && a > MIN_VALUE)
Console.WriteLine("max and min value is valid");
else
Console.WriteLine("max and min value is not valid");
}
public static void checkMax(int a) {
Console.Write("checkMax result of {0}: ", a);
if (a < MAX_VALUE)
Console.WriteLine("max value is valid");
else
Console.WriteLine("max value is not valid");
}
public static void checkMin(int a) {
Console.Write("checkMin result of {0}: ", a);
if (a > MIN_VALUE)
Console.WriteLine("min value is valid");
else
Console.WriteLine("min value is not valid");
Console.WriteLine("");
}
}
public class Driver {
public static void Main(string [] args) {
Valid v1 = new Valid(Test.checkInt);
v1 += new Valid(Test.checkMax);
v1 += new Valid(Test.checkMin);
v1(1);
v1(10);
v1(20);
v1(30);
v1(254);
v1(255);
v1(256);
}
}
A slightly different use is to speed up reflection; i.e. instead of using reflection each time, you can use Delegate.CreateDelegate to create a (typed) delegate to a method (a MethodInfo), and call that delegate instead. This is then much quicker per call, as the checks have already been done.
With Expression, you can also do the same to create code on the fly - for example, you can easily create an Expression that represents the + operator for a type chosen at runtime (to provide operator support for generics, which the language doesn't provide); and you can compile an Expression to a typed delegate - job done.
Delegates are used any time you use events - that's the mechanism by which they work.
In addition, delegates are very useful for things such as using LINQ queries. For example, many LINQ queries take a delegate (often Func<T,TResult>) which can be used for filtering.
subscribing eventhandlers to events
An example might be as seen here. You have a method to process an object that meets certain requirements. However, you want to be able to process the object in multiple ways. Instead of having to create separate methods, you can simply assign a matching method that processes the object to a delegate and pass the delegate to the method that selects the objects. That way, you can assign different methods to the one selector method. I tried to make this easily understandable.
I use delegates to communicate with threads.
For example, I might have a win forms app which downloads a file. The app starts a worker thread to do the download (which prevents the GUI from locking up). The worker thread uses delegates to send status messages (eg download progress) back to the main program, so that the GUI can update the status bar.
For event handler
To pass method in a method parameters
The first line of usage is to replace the Observer/Observable (events) pattern. The second, a nice elegant version of the Strategy pattern. Various other usages can be gathered, though more esoteric than these first two I think.
Events, other anynch operations
Any time you want to encapsulate behavior, but invoke it in a uniform way. Event Handlers, call-back functions, etc. You can accomplish similar things using Interfaces and casts, but sometimes, behavior isn't necessarily tied to a type or object. Sometimes you just have behavior you need to encapsulate.
Lazy parameter initialization! Besides all previous answers (strategy pattern, observer pattern, etc), delegates allow you to handle lazy initialization of parameters. For example, suppose you have a function Download() which takes quite a lot of time and returns a certain DownloadedObject. This object is consumed by a Storage depending on a certain Conditions. Typically, you would:
storage.Store(conditions, Download(item))
However, with delegates (more precisely, lambdas) you can do the following, by changing the signature of store so that it receives a Condition and a Func<Item,DownloadedObject> and use it like this:
storage.Store(conditions, (item) => Download(item))
Therefore, storage will only evaluate the delegate if necessary, executing download depending on Conditions.
Usage of delegates
Event Handling
Multi Casting
The comparison param in In Array.Sort(T[] array, Comparison comparison), List.Sort(Comparison comparison), etc
As far as I know, delegates can be converted to function pointers. This makes life MUCH easier when interoperating with native code that takes function pointers, as they can effectively be object-orientated, even though the original programmer didn't make any provision for that to happen.
Delegate's are used to call a method by it's reference.
For example:
delegate void del_(int no1,int no2);
class Math
{
public static void add(int x,int y)
{
Console.WriteLine(x+y);
}
public static void sub(int x,int y)
{
Console.WriteLine(x-y);
}
}
class Program
{
static void Main(string[] args)
{
del_ d1 = new del_(Math.add);
d1(10, 20);
del_ d2 = new del_(Math.sub);
d2(20, 10);
Console.ReadKey();
}
}