Pass Method as Parameter Using C#

Pass Method as Parameter using C#

You can use the Func delegate in .net 3.5 as the parameter in your RunTheMethod method. The Func delegate allows you to specify a method that takes a number of parameters of a specific type and returns a single argument of a specific type. Here is an example that should work:

public class Class1
{
public int Method1(string input)
{
//... do something
return 0;
}

public int Method2(string input)
{
//... do something different
return 1;
}

public bool RunTheMethod(Func<string, int> myMethodName)
{
//... do stuff
int i = myMethodName("My String");
//... do more stuff
return true;
}

public bool Test()
{
return RunTheMethod(Method1);
}
}

Pass a method as a parameter

You need to use a delegate, which is a special class that represents a method. You can either define your own delegate or use one of the built in ones, but the signature of the delegate must match the method you want to pass.

Defining your own:

public delegate int MyDelegate(Object a);

This example matches a method that returns an integer and takes an object reference as a parameter.

In your example, both methodA and methodB take no parameters have return void, so we can use the built in Action delegate class.

Here is your example modified:

public void PassMeAMethod(string text, Action method)
{
DoSomething(text);
// call the method
method();
}

public void methodA()
{
//Do stuff
}


public void methodB()
{
//Do stuff
}

public void Test()
{
//Explicit
PassMeAMethod("calling methodA", new Action(methodA));
//Implicit
PassMeAMethod("calling methodB", methodB);

}

As you can see, you can either use the delegate type explicitly or implicitly, whichever suits you.

C# Pass any method as parameter

In C# 8.0 using generics and Delegate Constraint you can do something like this:

using System;
using System.Collections.Generic;

namespace ConsoleApp
{

public class Program
{
public static void Main(params string[] args)
{
var app = new NetworkingApplication();
app.Register<Action<int, string>>(PacketType.Type1, Method1, 1, "string1 argument");
app.Register<Func<string, string>>(PacketType.Type2, Method2, "string2 argument");
app.OnPacketReceived(PacketType.Type1);
app.OnPacketReceived(PacketType.Type2);
}

public static void Method1(int arg1, string arg2)
{
Console.WriteLine($"Method1 Invoked with args: {arg1}, {arg2}");
}

public static string Method2(string arg1)
{
Console.WriteLine($"Method2 Invoked with args: {arg1}");
return "Foo";
}
}

public class NetworkingApplication
{
private readonly IDictionary<PacketType, DelegateInvoker> _registrations;

public NetworkingApplication()
{
_registrations = new Dictionary<PacketType, DelegateInvoker>();
}

public void Register<TDelegate>(PacketType packetType, TDelegate @delegate, params object[] args)
where TDelegate : Delegate
{
_registrations[packetType] = new DelegateInvoker(@delegate, args);
}

//invoke this when the packet is received
public void OnPacketReceived(PacketType type)
{
if (_registrations.TryGetValue(type, out var invoker))
{
invoker.Invoke();
}
}

private class DelegateInvoker
{
public DelegateInvoker(Delegate @delegate, object[] args)
{
Delegate = @delegate;
Arguments = args;
}

private Delegate Delegate { get; }
private object[] Arguments { get; }

public void Invoke()
{
Delegate.Method.Invoke(Delegate.Target, Arguments);
}
}
}





public enum PacketType
{
Type1,
Type2,
Type3
}
}

Passing a Function (with parameters) as a parameter?

It sounds like you want a Func<T>:

T GetCachedValue<T>(string key, Func<T> method) {
T value;
if(!cache.TryGetValue(key, out value)) {
value = method();
cache[key] = value;
}
return value;
}

The caller can then wrap this in many ways; for simple functions:

int i = GetCachedValue("Foo", GetNextValue);
...
int GetNextValue() {...}

or where arguments are involved, a closure:

var bar = ...
int i = GetCachedValue("Foo", () => GetNextValue(bar));

C# pass a method as a parameter without specifying a method signature

Your only real option is object function(object[]){} but as you say there are huge issues with interpreting the object actual type. C# is a strongly typed language unlike javascript and so the capabilities that you want are just not possible, and if they are then they shouldn't be used because you'll lose all of the advantages of using a strongly typed language in the first place.

C# pass methods as parameters

C# equivalent of function pointers are delegates. You can use Func and Action to pass methods as parameters. Func delegate represents method which takes N arguments and returns value, Action delegate represents void method.

Consider this

void (* myFunction)(int parameter) 

in C# would be

Action<int> 

C# Passing a method as a parameter to another method

You can use the Action delegate type.

public void ErrorDBConcurrency(DBConcurrencyException e, Action method)
{
if (MessageBox.Show("You must refresh the datasource") == DialogResult.OK)
method();
}

Then you can use it like this:

void MyAction()
{

}

ErrorDBConcurrency(e, MyAction);

If you do need parameters you can use a lambda expression.

ErrorDBConcurrency(e, () => MyAction(1, 2, "Test")); 

C# Passing Function as Argument

Using the Func as mentioned above works but there are also delegates that do the same task and also define intent within the naming:

public delegate double MyFunction(double x);

public double Diff(double x, MyFunction f)
{
double h = 0.0000001;

return (f(x + h) - f(x)) / h;
}

public double MyFunctionMethod(double x)
{
// Can add more complicated logic here
return x + 10;
}

public void Client()
{
double result = Diff(1.234, x => x * 456.1234);
double secondResult = Diff(2.345, MyFunctionMethod);
}

Pass a method as a parameter in C# from a different class

You would need to make an instance of class B inside class A and then call the method, For example, change your class A to:

public Class A
{
(...)
private B myClass = new B();
public bool Test()
{
return myClass.RunTheMethod(myClass.Method1);
}

(...)
}


Related Topics



Leave a reply



Submit