I am trying to learn the anonymous method and tried out this sample.
So, whenever I am trying to call WriteLog function i can just use
()=> { return "someLogData" };
The advantage is that, I need not have a separate function and can save lines of code.
public void WriteLog(Func<string> s)
{
Console.WriteLine(s);
}
But, the same does not work out with functions like
Console.WriteLine( ()=> {return "someString" } );
Why does .NET provide this anonymous method functionality but does not let to use it in one of its own kind?
There are no overloads of Console.WriteLine which accept a Func<string> - and indeed even your current WriteLog method won't do anything useful (as you'd need to invoke the delegate).
Where methods accepting specific delegates do exist - most prominently in LINQ, but elsewhere too - you can indeed use lambda expressions or anonymous methods to invoke them.
You can call Console.WriteLine using a lambda expression, but you need to cast it to a specific delegate type - as there are only conversions from lambda expressions to specific delegate or expression types, not just Delegate or object. So this will work:
Console.WriteLine((Func<string>)(() => "someLogData"));
Again though, it wouldn't be useful to do so anyway - you don't want to log the delegate, you want to log the result of invoking the delegate.
It doesn't make very much sense for Console.WriteLine to accept delegates IMO, but it would make more sense for more flexible logging, where you don't want to evaluate the string unless you're actually going to write it to a log.
Note that your WriteLog call itself can be simpler too:
WriteLog(() => "someLogData");
You need to have your anonymous method executed to get the string.
public void WriteLog(Func<string> s)
{
Console.WriteLine(s());
}
There is an advantage in this form:
public void WriteLog(Func<string> s)
{
Console.WriteLine(s);
}
let's imagine that inside it it's written as:
public void WriteLog(Func<string> s)
{
if (needToWriteLog)
{
Console.WriteLine(s);
}
}
now, let's say that you call it this way:
WriteLog(() => StringThatNeedsFiveSecondsToBuild())
and let's compare it to a similar WriteLog that only accepts a string as a parameter:
WriteLog(StringThatNeedsFiveSecondsToBuild())
The second WriteLog will always spend 5 seconds to build the string, even when needToWriteLog is false, while the first one will build it only if it's true.
Now, compare it to Console.WriteLine: Console.WriteLine will always print its content, so there is no need to use a delegate, because the 5 seconds will always be spent.
There are some methods that are similar in C#, the ones of the family Debug.* and Trace.*, but they are different. You use them like this:
Debug.WriteLine(StringThatNeedsFiveSecondsToBuild())
the trick is that they are defined like this:
[ConditionalAttribute("DEBUG")]
public static void WriteLine(string value)
so that if the DEBUG isn't defined, the whole Debug.WriteLine(StringThatNeedsFiveSecondsToBuild()) is removed, even if it had some side effects (like spending 5 seconds :-) )
All of this show something else: it's VERY important that the delegates you pass to your WriteLog AND the parameters you pass to the Debug.* and Assert.* be side effect free (clearly ignoring the time as a side effect, I mean "real" side effects like changing variable values), because you don't know if they'll really be executed.
Related
I have a method that needs to take the function and its owner class as the input arguments and then to proceed with its names with reflection. Of course I could take a couple of strings as the input args, so the method would look like this:
void Proceed(string className, string methodName)
{
Console.WriteLine($"{className}.{methodName} called");
//...
}
and would be called like this:
Proceed(nameof(Foo), nameof(Foo.Bar));
But I wonder if there is any way to avoid writing the nameof keyword every time I am trying to call the method. To me something like Proceed<Foo>(f => f.Bar) would look a lot nicer.
I suppose this could be solved with expressions. The problem I face is that if method Bar has arguments, you have to specify them explicitly when calling the method (which seems excessive in my case where you only going to need the name of the method later).
So, the best solution I managed to find is this one:
void Proceed<T>(Expression<Func<T, Action<object, object>>> expression)
{
//...
}
Yet it still specifies the argument method's signature in its own args and therefore is not generic enough.
I wonder if there is some way to pass the function as an argument without specifying its arguments (provided I am only going to need its name later, just like nameof keyword does).
I think you are looking for the usage of an event or delegate.
You can look up more information regarding those 2 online. The idea is that they store some methods with the same arguments so that later it knows what kind of arguments you need to call.
Yes, use the Delegate keyword.
See the answer here.
My program had a simple function newline() that would provide an int value to a int variable x.
public void autowordwrap(string wrapthisword)
{
//some code that does things irrelevant to this problem, with the string
x=newline();
//assume x is already declared properly
//do something with value from x
}
Problem started when I introduced a new function sameline()
I want to be able to do any one of these conveniently, at a time:
public void autowordwrap(string wrapthisword)
{
x=newline();
}
or,
public void autowordwrap(string wrapthisword)
{
x=sameline();
}
So, I thought of trying this:
public void autowordwrap(string wrapthisword, Func<void,int> linefunc)
{
x=linefunc;
}
which I can later call on requirement as:
autowordwrap(mystring,newline());
or,
autowordwrap(mystring,sameline());
But it is not quite working out for me!
It says keyword 'void' cannot be used in this context
Problem is:
What I want to do should be simple enough but I'm not quite understanding how it works. I understand that Action<> works for functions without return type and Func<> works for function with a return type.[Reference-1].
What I've gathered so far is:
MSDN tells me: To reference a method that has no parameters and returns void (or in Visual Basic, that is declared as a Sub rather than as a Function), use the Action delegate instead.
Since my newline() function is defined as an int-datatype, and it returns an integer after running, I thought Action<> didn't suit my needs.
This answer has what I need but for the life of me, I couldn't make it work for my specific purpose.
Problem Breakdown
I have two functions newline() and sameline()
I wish to pass any ONE out of the TWO of them as an argument of the function autowordwrap()
which means, in my Main Program, I will be using autowordwrap(somestring, newline()); or autowordwrap(somestring, sameline()); wherever necessary!
both newline() and sameline() are int-datatype functions who return integer value upon being called. For the sake of this problem, lets store it in int x
while trying to solve this, I'm assuming that using Func is used to pass nothing onto the function as an argument while calling example: newline(void) and the int part is used to define the function newline() or any function represented by delegate Func<> as one which returns an int value.
I have realized that what I have seemed to learn must be fundamentally flawed somehow somewhere. Please enlighten me. Reference links would be very helpful too.
Solving this problem in any way is acceptable. You do not need to do this in the way that I may have unintentionally rigidly outlined. Please feel free to explore creative solutions as long as they fulfill the intended purpose in C#
Yes, I acknowledge that THIS is a possible duplicate of this question but I couldn't make much sense of the helpful answer posted over there. Assuming, this will be the case for many future readers, I'm making this question and linking it to that question so that it may be helpful to people who'll face this same problem in the future.
Endnote:
This Question has been solved! The marked answer lays down the way for doing this and there is also some great explanation in the answers. If you are facing some errors while solving a similar question of this nature, you might be able to fix those my looking over screenshots of my own errors. They're here in the revision section no.4
Func<T> has to return some thing, it cannot be void, you have to use Action<T>, if you don't want to return anything.
and if you don't want to pass any input argument to the Func<T>, then you just need one parameter which is return type like:
Func<int> linefunc
you cannot define input type parameter for Func<T,TResult> as void, instead of that just remove the input type parameter of it,
your method definition would look like :
public void autowordwrap(string wrapthisword, Func<int> linefunc)
{
x=linefunc();
}
and call it like:
autowordwrap(mystring, newline);
autowordwrap(mystring, sameline);
You're very nearly there. There are a couple of issues.
First, from your code you appear to be passing the result of your functions in;
autowordwrap("foo", newline());
In this code, C# will invoke the newline function, getting a result. It will then pass the result of that function -- your int -- as the second parameter to autowordwrap.
What you're wanting to do is pass in the un-invoked function itself;
autowordwrap("foo", newline);
So long as the signature of the newline function is compatible with the signature required by autowordwrap, you'll be able to invoke that function inside autowordwrap.
The second part isn't so much the difference between Func<> and Action<>, but about the generic parameters.
The signature you want is a function which takes no parameters and returns an int. So it's reasonable to try
Func<void, int>
but actually, Func<> can take any number of generic types. All but the last are parameters; the last is the return value. So
Func<string, string, int>
corresponds to a method like
public int MyFunction(string s1, string s2) { return 0; }
What you're trying for is a function of no parameters, equivalent to
public int MyFunction() { reutrn 0; }
So the signature you're looking for is
Func<int>
That is, a function of no parameters, returning int. For clarity,
Action<int>
takes one integer parameter and reutrns nothing, equivalent to
public void MyAction(int myParam) { }
--
Oh, and to clarify;
Func<void, int>
Doesn't work because it's equivalent to writing this in C#
public int MyFunction(void x) {}
which is like saying 'a function which takes one parameter, which is a variable of type 'void''. That doesn't make sense, hence the compiler error.
Since your function doesn't need a delegate, it needs an int, you're better off avoiding delegates altogether, just pass the int value, and do this:
public void autowordwrap(string wrapthisword, int separator)
{
//some code that does things irrelevant to this problem, with the string
// if you need it in "x"
x=separator;
//do something with value from x
}
autowordwrap(mystring,newline());
// or
autowordwrap(mystring,sameline());
The general idea for creating clean high quality code is for a function to accept the value(s) it requires to do its specific task, and not some complex input that is "bigger" then that.
In C# I can do this:
delegate void myFunctionDelegate<T>(T arg);
In C++, I understand that I need to use an alias to a template for a function pointer, but the syntax is so bizaare that all of the examples I find just confuse me more.
The following is wrong; how can I correct it?
template<typename T>
using myFunctionDelegate = void (*)(T arg);
I want to use it like so:
template<class T> class Foo
{
...
void someOtherFunction(myFunctionDelegate callback)
{
...
callback(someValue);
}
}
and then:
myClassInstance.someOtherFunction([&](T arg) {
// do something with the callback argument
});
What you have almost works syntactically; the use of myFunctionDelegate simply needs a type argument:
void someOtherFunction(myFunctionDelegate<T> callback)
^^^
And the alias parameter names are optional if you aren't getting any particular benefit from them:
template<typename T>
using myFunctionDelegate = void(*)(T);
However, there is a larger problem: function pointers don't handle state. The lambda used in your sample call uses state by the capturing it does. Thus, a capturing lambda cannot be converted to a function pointer. When it's so handy to pass in such a lambda, function arguments should support that.
There are two common ways of doing so. The first is to forget about forcing a specific return and parameter type. Instead, let the caller pass any object (lambda, function pointer, functor, the result of std::bind) that can be called the way your function calls it:
template<typename Callable>
void someOtherFunction(Callable callback) {
...
callback(someValue);
}
If the call doesn't work, the code will fail to compile1 (with an error that unfortunately isn't too helpful, but the future Concepts additions can easily help there).
On the other hand, you might want to explicitly specify the function type. C++ has a general-purpose type to store any callable object (see the above list). That type is std::function. It's a bit more heavyweight than a simple template parameter, but useful when you need it.
template<typename T>
using myFunctionDelegate = std::function<void(T)>;
void someOtherFunction(const myFunctionDelegate<T> &callback) {...}
[1]: This isn't always true (see SFINAE), but it probably will be as far as you're concerned.
std::function<void(T)> myFunctionDelegate is the (very) rough equivalent of delegate void myFunctionDelegate<T>(T arg)
std::function<void(T)> follows value semantics (it behaves more like an int than a C# object reference) which makes things different.
A lambda closure ([](T t){/*code*/}) whose lifetime (or copies of it) outlives the local scope should not use & based capture. Instead use = based capture (which may require extra work). If the code you are calling does not store a copy of the delegate beyond the lifetime of the call, [&] is optimal. In C++ the lifetime of data is something you need concern yourself with.
This is not intended as a full tutorial on how lambdas and std::function work, but just to point you in the right direction.
Can someone please break down what a delegate is into a simple, short and terse explanation that encompasses both the purpose and general benefits? I've tried to wrap my head around this and it's just not sinking in.
I have a function:
public long GiveMeTwoTimesTwo()
{
return 2 * 2;
}
This function sucks. What if I want 3 * 3?
public long GiveMeThreeTimesThree()
{
return 3 * 3;
}
Too much typing. I'm lazy!
public long SquareOf(int n)
{
return n * n;
}
My SquareOf function doesn't care what n is. It will operate properly for any n passed in. It doesn't know exactly what number n is, but it does know that n is an integer. You can't pass "Haha not an integer" into SquareOf.
Here's another function:
public void DoSomethingRad()
{
int x = 4;
long y = SquareOf(x);
Console.WriteLine(y);
}
Contrary to its name, DoSomethingRad doesn't actually do anything rad. However, it does write the SquareOf(4) which is 16. Can we change it to be less boring?
public void DoSomethingRad(int numberToSquare)
{
long y = SquareOf(numberToSquare);
Console.WriteLine(y);
}
DoSomethingRad is clearly still pretty fail. But at least now we can pass in a number to square, so it won't write 16 every time. (It'll write 1, or 4, or 9, or 16, or... zzzz still kinda boring).
It'd be nice if there was a way to change what happens to the number passed in. Maybe we don't want to square it; maybe we want to cube it, or subtract it from 69 (number chosen at random from my head).
On further inspection, it seems as though the only part of SquareOf that DoSomethingRad cares about is that we can give it an integer (numberToSquare) and that it gives us a long (because we put its return value in y and y is a long).
public long CubeOf(int n)
{
return n * n * n;
}
public void DoSomethingLeet(int numberToSquare)
{
long y = CubeOf(numberToSquare);
Console.WriteLine(y);
}
See how similar DoSomethingLeet is to DoSomethingRad? If only there was a way to pass in behavior (DoX()) instead of just data (int n)...
So now if we want to write a square of a number, we can DoSomethingRad and if we want to write the cube of a number, we can DoSomethingLeet. So if we want to write the number subtracted from 69, do we have to make another method, DoSomethingCool? No, because that takes too damn much typing (and more importantly, it hinders our ability to alter interesting behavior by changing only one aspect of our program).
So we arrive at:
public long Radlicious(int doSomethingToMe, Func<int, long> doSomething)
{
long y = doSomething(doSomethingToMe);
Console.WriteLine(y);
}
We can call this method by writing this:
Radlicious(77, SquareOf);
Func<int, long> is a special kind of delegate. It stores behavior that accepts integers and spits out longs. We're not sure what the method it points to is going to do with any given integer we pass; all we know is that, whatever happens, we are going to get a long back.
We don't have to give any parameters to SquareOf because Func<int, long> describes behavior, not data. Calling Radlicious(77, SquareOf) just gives Radlicious the general behavior of SquareOf ("I take a number and return its square"), not what SquareOf will do to any specific integer.
Now if you have understood what I am saying, then you have already one-upped me, for I myself don't really get this stuff.
* END ANSWER, BEGIN WANDERING IDIOCY *
I mean, it seems like ints could be perceived as just really boring behavior:
static int Nine()
{
return 9;
}
That said, the line between what is data and behavior appears to blur, with what is normally perceived as data is simply boring-ass behavior.
Of course, one could imagine super "interesting" behavior, that takes all sorts of abstract parameters, but requires a ton of information to be able to call it. What if it required us to provide the source code that it would compile and run for us?
Well, then our abstraction seems to have gotten us all the way back to square one. We have behavior so abstract it requires the entire source code of our program to determine what it's going to do. This is fully indeterminate behavior: the function can do anything, but it has to be provided with everything to determine what it does. On the other hand, fully determinate behavior, such as Nine(), doesn't need any additional information, but can't do anything other than return 9.
So what? I don't know.
In the simplest possible terms, it's essentially a pointer to a method.
You can have a variable that holds a delegate type (just like you would have an int variable that can hold an int type). You can execute the method that the delegate points to by simply calling your variable like a function.
This allows you to have variable functions just like you might have variable data. Your object can accept delegates from other objects and call them, without having to define all the possible functions itself.
This comes in very handy when you want an object to do things based on user specified criteria. For example, filtering a list based on a user-defined true/false expression. You can let the user specify the delegate function to use as a filter to evaluate each list item against.
A delegate is a pointer to a method. You can then use your delegate as a parameter of other methods.
here is a link to a simple tutorial.
The question I had was 'So, why would I want to do that?' You won't really 'get it' until you solve a programming problem with them.
It's interesting that no-one has mentioned one of key benefits of delegation - it's preferable to sub-classing when you realise that inheritance is not a magic bullet and usually creates more problems than it solves. It is the basis of many design patterns, most notably the strategy pattern.
A delegate instance is a reference to a method. The reason they are useful is that you can create a delegate that is tied to a particular method on a particular instance of a type. The delegate instance allows you to invoke that method on that particular instance even if the object on which you will invoke the method has left your lexical scope.
The most common use for delegate instances like this is to support the concept of callbacks at the language level.
It simply references a method. They come in great use with working with cross threading.
Here is an example right out of my code.
//Start our advertisiment thread
rotator = new Thread(initRotate);
rotator.Priority = ThreadPriority.Lowest;
rotator.Start();
#region Ad Rotation
private delegate void ad();
private void initRotate()
{
ad ad = new ad(adHelper);
while (true)
{
this.Invoke(ad);
Thread.Sleep(30000);
}
}
private void adHelper()
{
List<string> tmp = Lobby.AdRotator.RotateAd();
picBanner.ImageLocation = #tmp[0].ToString();
picBanner.Tag = tmp[1].ToString();
}
#endregion
If you didnt use a delegate you wouldn't be able to crossthread and call the Lobby.AdRotator function.
Like others have said, a delegate is a reference to a function. One of the more beneficial uses(IMO) is events. When you register an event you register a function for the event to invoke, and delegates are perfect for this task.
In the most basic terms, a delegate is just a variable that contains (a reference to) a function. Delegates are useful because they allow you to pass a function around as a variable without any concern for "where" the function actually came from.
It's important to note, of course, that the function isn't being copied when it's being bundled up in a variable; it's just being bound by reference. For example:
class Foo
{
public string Bar
{
get;
set;
}
public void Baz()
{
Console.WriteLine(Bar);
}
}
Foo foo = new Foo();
Action someDelegate = foo.Baz;
// Produces "Hello, world".
foo.Bar = "Hello, world";
someDelegate();
In most simplest terms, the responsibility to execute a method is delegated to another object. Say the president of some nation dies and the president of USA is supposed to be present for the funeral with condolences message. If the president of USA is not able to go, he will delegate this responsibility to someone either the vice-president or the secretary of the state.
Same goes in code. A delegate is a type, it is an object which is capable of executing the method.
eg.
Class Person
{
public string GetPersonName(Person person)
{
return person.FirstName + person.LastName;
}
//Calling the method without the use of delegate
public void PrintName()
{
Console.WriteLine(GetPersonName(this));
}
//using delegate
//Declare delegate which matches the methods signature
public delegate string personNameDelegate(Person person);
public void PrintNameUsingDelegate()
{
//instantiate
personNameDelegate = new personNameDelegate(GetPersonName);
//invoke
personNameDelegate(this);
}
}
The GetPersonName method is called using the delegate object personNameDelegate.
Alternatively we can have the PrintNameUsingDelegate method to take a delegate as a parameter.
public void PrintNameUsingDelegate(personNameDelegate pnd, Person person)
{
pnd(person);
}
The advantage is if someone want to print the name as lastname_firstname, s/he just has to wrap that method in personNameDelegate and pass to this function. No further code change is required.
Delegates are specifically important in
Events
Asynchronous calls
LINQ (as lambda expressions)
If you were going to delegate a task to someone, the delegate would be the person who receives the work.
In programming, it's a reference to the block of code which actually knows how to do something. Often this is a pointer to the function or method which will handle some item.
In the absolute most simplest terms I can come up with is this: A delegate will force the burdens of work into the hands of a class that pretty much knows what to do. Think of it as a kid that doesn't want to grow up to be like his big brother completely but still needs his guidance and orders. Instead of inheriting all the methods from his brother (ie subclassing), he just makes his brother do the work or The little brother does something that requires actions to be taken by the big brother. When you fall into the lines of Protocols, the big brother defines what is absolutely required, or he might give you flexibility to choose what you want to make him do in certain events (ie informal and formal protocols as outlined in Objective-C).
The absolute benefit of this concept is that you do not need to create a subclass. If you want something to fall in line, follow orders when an event happens, the delegate allows a developed class to hold it's hand and give orders if necessary.
I discovered something very strange that I'm hoping to better understand.
var all = new List<int[]>{
new int[]{1,2,3},
new int[]{4,5,6},
new int[]{7,8,9}
};
all.ForEach(n => n.ForEach(i => Console.WriteLine(i)));
which can be rewritten as:
...
all.ForEach(n => n.ForEach(Console.WriteLine));
How is it possible to leave out the lambda expression parameter (i=>) and still have the current item passed to console.WriteLine?
Thanks for any insight.
-Keith
List<T>.ForEach is looking for an Action<T>. When you write
n.ForEach(Console.WriteLine);
what you have here is one of the members of the method group Console.WriteLine playing the role of an Action<T>. The compiler will look for the best overload of Console.WriteLine that eats instances of int. In fact, it will use the overload Console.WriteLine(int). It will then use this overload to play the role of an Action<int>.
For details on how this is done, see ยง6.6 of the specification (Method group conversions).
However, when you write
n.ForEach(i => Console.WriteLine(i));
we actually have a very different Action<int> In the first case, the Action<int> was Console.WriteLine(int). Here, the Action<int> is equivalent to you having written
public static void DoSomething(int i) {
Console.WriteLine(i);
}
and then
n.ForEach(DoSomething);
(Of course, the compiler has to go through the same method group process as described above to figure out what is meant by DoSomething).
The point is that in the first case the Action<int> is Console.WriteLine(int). However, in the second case the Action<int> is a middle man (the lambda expression) that itself will call Console.WriteLine(int).
This is less confusing if you consider what is really happening.
You are passing a method to a delegate argument. Most of the time, we think of delegates in the context of events, but they can be parameters to methods as well. It doesn't seem odd when a method is added to an event without arguments, it just is unusual looking when executed in this context.
Before lambdas, you had to do this all the time, and it was such a pain that one would never consider using a library that looked like LINQ. With Lambdas, this is easier to do, but you can always do the old way as well.