I'm trying to list some of my class' methods in an enum so that I can call these methods depending on the enum selected. I tried using ToString() and GetMethod(string) with no luck. If there's a better way to dynamically change which method my delegate will call from the list of enums I'd appreciate the help! I'm very new to C#, and I'm also wondering if there are alternative ways of storing method pointers. I looked into reflection on these boards and wasn't having much luck in either casting or assigning from enums.
public enum funcEnum { FirstFunction, SecondFunction };
public funcEnum eList;
public delegate void Del();
public Del myDel;
void Start() {
myDel = FirstFunction; //pre-compiled assignment
myDel(); //calls 'FirstFunction()' just fine
this below could be changed during runtime, it isn't normally going to be in Start()
eList = funcEnum.SecondFunction; //this could be changed during runtime
myDel = eList.ToString();
obvious error, myDel looking for method, not sure how I can retrieve/convert enum value to method to be assigned to the delegate, trying to call a method with having prior knowledge of assignment. Basically wanting the enum list to contain names of methods within this class.
myDel(); //doesn't work
}
public void FirstFunction() {
Debug.Log("First function called");
}
public void SecondFunction() {
Debug.Log("Second function called");
}
You can't simply assign a string to a method / delegate. Instead of this:
myDel = eList.ToString();
You can use the Delegate.CreateDelegate method.
Something like this would for work instance methods:
myDel = (Del)Delegate.CreateDelegate(typeof(Del), this, eList.ToString());
Or this for static methods:
myDel = (Del)Delegate.CreateDelegate(typeof(Del), this.GetType(), eList.ToString());
Note I've assumed in both cases the methods are defined on the same class that's invoking the code. You'd have to modify this a bit to call methods on another object.
Another alternative if you're interested is to use Reflection via MethodInfo:
var method = typeof(YourClass).GetMethod(eList.ToString());
method.Invoke(new YourClass(), null);
Related
base on msdn pages, when we declare a delegate we do need to specify return value and also argument of the method that would be called via delegate.
my question:
let's say I have a method as:
public int MethodA(bool bValue) and also void MethodB(int iValue)
Do I need to declare two different delegates here for each method or I can do it using one?
Thanks.
Do I need to declare two different delegates here for each method or I can do it using one?
Since these methods have completely different signatures, you need different delegates. However, you can use the built-in Func<bool, int> and Action<int> delegates instead of declaring your own delegate types.
For example, you could use:
Func<bool,int> delegateA = this.MethodA;
Action<int> delegateB = this.MethodB;
// or: Action<int> delegateB = new Action<int>(this.MethodB);
The point of declaring delegates in the first place is so that you could call a method without seeing its declaration. That is why you need a different delegate type for each function signature that you are planning to call indirectly through a delegate.
Instead of defining a separate method and then using a delegate variable to point to it, you can shorten the code using an anonymous method.
class Program{
delegate void MethodsDelegate(string Message);
static void Main(string[] args){
MethodsDelegate method = delegate(string Message){
Console.WriteLine(Message);
};
//---call the delegated method---
method("Using anonymous method.");
Console.ReadLine();
}
}
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.
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.
A delegate is a function pointer. So it points to a function which meets the criteria (parameters and return type).
This begs the question (for me, anyway), what function will the delegate point to if there is more than one method with exactly the same return type and parameter types? Is the function which appears first in the class?
Thanks
The exact method is specified when you create the Delegate.
public delegate void MyDelegate();
private void Delegate_Handler() { }
void Init() {
MyDelegate x = new MyDelegate(this.Delegate_Handler);
}
As Henk says, the method is specified when you create the delegate. Now, it's possible for more than one method to meet the requirements, for two reasons:
Delegates are variant, e.g. you can use a method with an Object parameter to create an Action<string>
You can overload methods by making them generic, e.g.
static void Foo() {}
static void Foo<T>(){}
static void Foo<T1, T2>(){}
The rules get quite complicated, but they're laid down in section 6.6 of the C# 3.0 spec. Note that inheritance makes things tricky too.
So it points to a function which meets the criteria (parameters and return type).
Nope.
To add some background to Henk's Answer:
Just like int x is an variable which can contain integers, A delegate is a variable which can contain functions.
It points to whatever function you tell it to point to.
EG:
// declare the type of the function that we want to point to
public delegate void CallbackHandler(string); //
...
// declare the actual function
public void ActualCallbackFunction(string s){ ... }
...
// create the 'pointer' and assign it
CallbackHandler functionPointer = ActualCallbackFunction;
// the functionPointer variable is now pointing to ActualCallbackFunction