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
How to Get Started With Developing Internet Explorer Extensions
How to Load Dll (Module Could Not Be Found Hresult: 0X8007007E)
Pre & Post Increment Operator Behavior in C, C++, Java, & C#
How to Specify a [Dllimport] Path At Runtime
How to Run a Python Script from C#
How to Avoid Dependency Injection Constructor Madness
What Is a Nullreferenceexception, and How to Fix It
What Is an Indexoutofrangeexception/Argumentouto
frangeexception and How to Fix It
Random Number Generator Only Generating One Random Number
Understanding Garbage Collection in .Net
Difference Between a Reference Type and Value Type in C#
How to Enable Assembly Bind Failure Logging (Fusion) in .Net
Implementing Inotifypropertychanged - Does a Better Way Exist
How to Make a Textbox That Only Accepts Numbers
How to Dynamically Compile and Execute C# Code Fragments
The Entity Cannot Be Constructed in a Linq to Entities Query