I am used to Javascript where I can simply pass a function as a parameter to use as a callback later. It was nice and easy.
Now I am writing an app in c# and would like to accomplish the same thing.
Basically, my app is like the following and requires an authentication token. However, at the getData stage, if the token is expired, I need to call refreshToken(). How do I pass the callback function through refreshToken() so getData knows what to call when the token is refreshed?
Here's a diagram of what I would do in Javascript, but would I go about doing this in C#, or just passing callbacks in general?:
getData(callback);
// Looks like the token is expired, exiting the getData function and refreshing token
refreshToken(function(){ getData(callback); });
// Token is refreshed, now call getData()
getData(callback);
// Callback is run
Or, alternatively, instead of using a ton of callbacks I could do the refreshToken call synchronously. However, RestSharp on WP7 for whatever reason isn't showing Execute, just ExecuteAsync, which is what I use now. Does anyone know why this method doesn't seem to exist for me?
To pass a function as a parameter in C# one uses a delegate. A delegate specifies the expected return type and arguments of the function being passed into a method and your callback method must conform to this specification, otherwise your code will not compile.
Delegates are generally declared directly within a namespace and take the form:
<access modifier(s)> delegate <return type> <DelegateName>([argument list]);
For example, in C# a delegate named FooCallback representing a callback function for the Foo method that takes no arguments and returns void would look like this:
namespace Demo
{
public delegate void FooCallback();
}
A function that takes a FooCallback parameter would look like this:
namespace Demo
{
//delegate for a FooCallback method from the previous code block
public delegate void FooCallback();
public class Widget
{
public void BeginFoo(FooCallback callback)
{
}
Asssuming that you have a method that matches the signature of a delegate you can simply pass it's name as the value of the delegate parameter. For example, assuming you have a function named MyFooCallback you can pass it as a parameter to the StartFoo method like this:
using Demo; //Needed to access the FooDelegate and Widget class.
namespace YourApp
{
public class WidgetUser
{
private Widget widget; //initialization skipped for brevity.
private void MyFooCallback()
{
//This is our callback method for StartFoo. Note that it has a void return type
//and no parameters, just like the definition of FooCallback. The signature of
//the method you pass as a delegate parameter MUST match the definition of the
//delegate, otherwise you get a compile-time error.
}
public void UseWidget()
{
//Call StartFoo, passing in `MyFooCallback` as the value of the callback parameter.
widget.BeginFoo(MyFooCallback);
}
}
}
While it is possible to define a delegate with arguments, it is not possible to pass an argument list alongside the method name as one normally does when invoking a method
namespace Demo
{
public delegate void FrobCallback(int frobberID);
//Invalid Syntax - Can't pass in parameters to the delegate method this way.
BeginFrob(MyFrobCallback(10))
}
When a delegate specifies parameters, the method that invokes the delegate takes the arguments needed by the delegate and passes them to the delegate method when it is called:
BeginFrob(MyFrobCallback, 10)
The BeginFrob method would then invoke the MyFrobCallback with the passed in frobberID value of 10 like this:
public void BeginFrob(FrobCallback callback, int frobberID)
{
//...do stuff before the callback
callback(frobberID);
}
Lambda Expressions allow you to define a method where it is used rather than needing to explicitly declare it
BeginFoo((int frobberID) => {your callback code here;});
In summary, delegates are a means for methods to be passed to other methods as parameters.
There are no synchronous web calls in silverlight / wp7, so that is not a restsharp problem.
As arthur said you want delegates.
function getData(Action<string> callback) {
if (token.needRefresh) {
refrshToken(() => getData(callback) );
return;
}
// get Data
callback(data);
}
function refreshToken(Action callback) {
// token.refresh
callback();
}
What you're looking for is delegate, anonymous delegate or Func
Related
Java can implement interface OnCustomEventListener such as:
classA.setCustomEventListener(new OnCustomEventListener(){
public void onEvent(){
//do whatever you want to do when the event is performed.
}
Does C# can do the same?
No, C# has no direct equivalent to that code, howeever the typical way you would pass some "action" or "callback" to a method would be using a delegate, or the shorter-formed Lambda expression.
classA.SetCustomEventListener( () => {
//do whatever you want to do when the event is performed.
});
The code for that method would look like
public void SetCustomEventListener (Action action)
{
action(); // execute the Lambda passed in
}
Ref:
Action delegate
So I'm a little bit confused about delegates in C#.... what do they do and how are they useful? I've read a few tutorials, and I don't really get exactly what they're supposed to do (everyone relates them to function pointers in C, and I've never programmed in C).
So... what do delegates do? What's a scenario in which I should use them? How would I then use them?
The other answers are good, but here's another way to think about delegates that might help. Imagine that a delegate is nothing more than an interface. When you see:
delegate void Action();
think:
interface IAction
{
void Invoke();
}
And when you see:
Action myAction = foo.Bar;
think:
class FooBarAction : IAction
{
public Foo Receiver { get; private set; }
public FooBarAction(Foo foo)
{
this.Receiver = foo;
}
public void Invoke()
{
this.Receiver.Bar();
}
}
...
IAction myAction = new FooBarAction(foo);
And when you see
myAction();
think
myAction.Invoke();
The actual details of what types get constructed are a bit different, but fundamentally that's what's happening. A delegate is simply an object with a method called Invoke, and when you call that method, it calls some other method on some other object on your behalf. That's why it's called a "delegate" -- because it delegates the call to another method of another object.
Delegates are sort of like objects that represent a method call. One useful way they can be used are as callbacks. For example, imagine you have a method that does something asynchronous, and you want the caller to be able to specify what they want to happen once it completes (Action is a type of delegate):
public void DoSomething(Action whatToDoWhenDone)
{
// Your code
// See how the delegate is called like a method
whatToDoWhenDone();
}
A user of DoSomething can now specify the callback as a parameter:
public void AnotherMethod()
{
DoSomething(ShowSuccess); // ShowSuccess will be called when done
}
public void ShowSuccess()
{
Console.WriteLine("Success!");
}
You can also use lamba expressions as a shorter way of writing your delegate:
public void AnotherMethod()
{
DoSomething(() => Console.WriteLine("Success!"));
// Also DoSomething(delegate() { Console.WriteLine("Success!"); });
}
Callbacks are far from the only use cases for delegates. Hopefully this shows you some of their power: the ability to have code to be executed as a variable.
Delegates allow you to treat functions as if they were any other variable. A delegate type defines the signature of the function, that is, what the function returns, and the number and type of arguments that it takes:
// This is the delegate for a function that takes a string and returns a string.
// It can also be written using the framework-provided Generic delegate Func, as
// Func<String, String>
delegate String StringToStringDelegate(String input);
You can define a variable of this type, and assign it to an existing method. I use the generic as an example, because that is the more common usage in .net since 2.0:
String Reverse(String input) {
return input.Reverse();
}
Func<String, String> someStringMethod = new Func<String, String>(Reverse);
// Prints "cba":
Console.WriteLine(someStringMethod("abc"));
You can also pass functions around this way:
String Reverse(String input) {
return input.Reverse();
}
String UpperCase(String input) {
return input.ToUpper();
}
String DoSomethingToABC(Func<String, String> inputFunction) {
return inputFunction("abc");
}
var someStringMethod = new Func<String, String>(Reverse);
// Prints "cba":
Console.WriteLine(DoSomethingToABC(someStringMethod));
var someOtherStringMethod = new Func<String, String>(UpperCase);
// Prints "ABC":
Console.WriteLine(DoSomethingToABC(someOtherStringMethod));
In a big application it is often required to other parts of the application based on some condition or something else. The delegate specifies the address of the method to be called. In simple manner a normal event handler implements the delegates in the inner layers.
The oversimplified answer is that a delegate is basically a "pointer" to a block of code, and the benefit is that you can pass this block of code into other functions by assigning your block of code to a variable.
The reason people relate Delegates to C function pointers is because this is in essence what delegation is all about, I.e.: Pointers to methods.
As an example:
public void DoSomething(Action yourCodeBlock)
{
yourCodeBlock();
}
public void CallingMethod()
{
this.DoSomething(
{
... statements
});
this.DoSomething(
{
... other statements
});
}
There are naturally lots of ways to invoke delegates as all of the tutorials will show you. The point is though that it allows you to "delegate" functionality in such a way that you can call into methods without necessarily knowing how they work, but simply trusting that they will be taken care of. In other words, I might create a class that implements a "DoSomething()" function, but I can leave it up to someone else to decide what DoSomething() will do later on.
I hope that helps. :-)
Delegates are a way to call back into your code when a long running operation completes or when an event occurs. For example, you pass a delegate to a method that asynchronously downloads a file in the background. When the download is complete, your delegate method would be invoked and it could then take some action such as processing the file's contents.
An event handler is a special type of delegate. For example, an event handler delegate can respond to an event like a mouse click or key press. Events are by far the most common type of delegate. In fact, you will typically see the event keyword used far more often in C# code than the delegate keyword.
You can think of it as a type in which you may store references to functions. That way you can in effect, store a function in a variable so you may call it later like any other function.
e.g.,
public delegate void AnEmptyVoidFunction();
This creates a delegate type called AnEmptyVoidFunction and it may be used to store references to functions that return void and has no arguments.
You could then store a reference to a function with that signature.
public static void SomeMethod() { }
public static int ADifferentMethod(int someArg) { return someArg; }
AnEmptyVoidFunction func1 = new AnEmptyVoidFunction(SomeMethod);
// or leave out the constructor call to let the compiler figure it out
AnEmptyVoidFunction func2 = SomeMethod;
// note that the above only works if it is a function defined
// within a class, it doesn't work with other delegates
//AnEmptyVoidFunction func3 = new AnEmptyVoidFunction(ADifferentMethod);
// error wrong function type
Not only can it store declared functions but also anonymous functions (i.e., lambdas or anonymous delegates)
// storing a lambda function (C#3 and up)
AnEmptyVoidFunction func4 = () => { };
// storing an anonymous delegate (C#2)
AnEmptyVoidFunction func5 = delegate() { };
To call these delegates, you can just invoke them like any other function call. Though since it is a variable, you may want to check if it is null beforehand.
AnEmptyVoidFunction func1 = () =>
{
Console.WriteLine("Hello World");
};
func1(); // "Hello World"
AnEmptyVoidFunction func2 = null;
func2(); // NullReferenceException
public static void CallIt(AnEmptyDelegate func)
{
// check first if it is not null
if (func != null)
{
func();
}
}
You would use them any time you needed to pass around a method that you wish to invoke. Almost in the same way that you may pass instances of objects so you may do what you wish with them. The typical use case for delegates is when declaring events. I have written another answer describing the pattern so you can look at that for more information on how to write those.
Say I have a function. I wish to add a reference to this function in a variable.
So I could call the function 'foo(bool foobar)' from a variable 'bar', as if it was a function. EG. 'bar(foobar)'.
How?
It sounds like you want to save a Func to a variable for later use. Take a look at the examples here:
using System;
public class GenericFunc
{
public static void Main()
{
// Instantiate delegate to reference UppercaseString method
Func<string, string> convertMethod = UppercaseString;
string name = "Dakota";
// Use delegate instance to call UppercaseString method
Console.WriteLine(convertMethod(name));
}
private static string UppercaseString(string inputString)
{
return inputString.ToUpper();
}
}
See how the method UppercaseString is saved to a variable called convertMethod which can then later be called: convertMethod(name).
Using delegates
void Foo(bool foobar)
{
/* method implementation */
}
using Action delegate
Public Action<bool> Bar;
Bar = Foo;
Call the function;
bool foobar = true;
Bar(foobar);
Are you looking for Delegates?
You need to know the signature of the function, and create a delegate.
There are ready-made delegates for functions that return a value and for functions that have a void return type. Both of the previous links point to generic types that can take up to 15 or so type arguments (thus can serve for functions taking up to that many arguments).
If you intend to use references to functions in a scope larger than a local scope, you can consider defining your own custom delegates. But most of the time, Action and Func do very nicely.
Update:
Take a look at this question regarding the choice between defining your own delegates or not.
This is my test code:
class PassingInActionStatement
{
static void Main(string[] args)
{
var dsufac = new DoSomethingUsefulForAChange();
dsufac.Do(WriteToConsole);
dsufac.Do2(s => WriteToConsoleWithSomethingExtra("Test"));
dsufac.Do(WriteToConsoleWithSomethingExtra("Test")); // Does not compile
}
internal static void WriteToConsole()
{
Console.WriteLine("Done");
}
internal static void WriteToConsoleWithSomethingExtra(String input)
{
Console.WriteLine(input);
}
}
internal class DoSomethingUsefulForAChange
{
internal void Do(Action action)
{
action();
}
internal void Do2(Action<String> action)
{
action("");
}
}
The first 2 calls work but I am wondering why the 3rd one does not. I do not fancy the code inside Do2 as it seems strange that I have type type action("") in there in order to get it to work.
Could someone please explain the 2 things I do not understand please?
Why I can not write the third line like that with calling Do
Why I have to write action("") in order get it to work in Do2
dsufac.Do(WriteToConsoleWithSomethingExtra("Test"));
actually calls the function first (WriteToConsoleWithSomethingExtra("Test")) and then attempts to pass the result into Do. Since there is no result (void), it's not possible.
What you actually want is this:
dsufac.Do(() => WriteToConsoleWithSomethingExtra("Test"));
The inner part declares a function that takes nothing (the () => bit), which calls WriteToConsoleWithSomethingExtra("Test") when executed. Then your dsufac.Do call will receive an action, like it expects.
As for Do2 - you've declared it as taking Action<String>, which means that action is a function that takes one argument. You have to pass it a string. That string might be empty, like in your action("") example, or it might be passed in externally, as in something like this:
dsufac.Do3(WriteToConsole, "Test");
...
internal void Do3(Action<String> action, String str)
{
action(str);
}
In your code
dsufac.Do(WriteToConsoleWithSomethingExtra("Test"));
is interpreted like the following
var variable = WriteToConsoleWithSomethingExtra("Test");
dsufac.Do(variable);
As the return type of WriteToConsoleWithSomethingExtra("Test") is void, so you can not actually pass it to dsufac.Do(). That is why its not getting compiled. But for the first one
dsufac.Do(WriteToConsole);
you are not calling the function, rather you are passing it as a method group, which is later get invoked in the Do() method of dsufac object. But if you want to write the 3rd line as the 1st one, you can use
dsufac.Do(() => WriteToConsoleWithSomethingExtra("Test"));
Do expects an Action (i.e. method which take no parameters and returns no value). Hence WriteToConsoleWithSomethingExtra is not a valid fit - takes one string parameter.
Do2 accepts an Action<T> (i.e. method which takes in one T parameter and returns no value). Hence when you invoke the delegate/action you need to supply one parameter of type T, here String.
I have a recuring method which shows up many times in my code its basically checking to make sure that the connection to the odbc is ok and then connects but each time this method is called it calls another method and each instance of the main method this one is different, as each method is about 8 lines of code having it 8 times in the code isnt ideal.
so basically i would like to have just one method which i can call passing the name of the new method as an arguement.
so basically like:
private void doSomething(methodToBeCalled)
{
if(somthingistrue)
{
methodToBeCalled(someArgument)
}
}
is this possible?
thanks in advance
As already said, you can use delegates for this:
// as in the original post:
private void doSomething(Action methodToBeCalled)
{
if (somethingIsTrue)
{
methodToBeCalled();
}
}
For methods without any arguments, this method is called e.g. as follows:
private void someMethod()
{
// ...
}
doSomething(someMethod);
If you want to call a method with arguments, you can wrap a lambda function around it:
private void someMethodWithArgument(int arg)
{
// ...
}
doSomething( () => someMethodWithArgument(42) );
Of course, if your methods to be called always take the same kind of argument, you can declare your doSomething method so that it accepts an Action<T> / Action<T,T> / etc. argument instead. If you want the called methods to return a value, use a delegate from the Func<T> family instead.
You can use delegates, this is much like a pointer to a function, you can pass a delegate to the method, which will invoke it with the parameter.
public delegate void Del(string message);
// Create a method for a delegate.
public static void DelegateMethod(string message)
{
System.Console.WriteLine(message);
}
// Instantiate the delegate.
Del handler = DelegateMethod;
// Call the delegate.
handler("Hello World");
In your case
private void doSomething(Del methodToBeCalled)
{
if(somthingistrue)
{
methodToBeCalled(someArgument)
}
}
is this possible?
Delegates
use Delegates as your method argument and you can point the delegate to whichever method you want, providing you stick to your delegate signature.
You could also use reflection. Which one is better to use (reflection vs. delegates) depends on the rest of your code. If you're always calling methods that take the same parameters, then a delegate is probably most appropriate. If you need to call methods that take different parameters, then you probably have to use reflection. Looking at your question, it kind of looks like your methods take no parameters, so I'd use delegates as mentioned before.