I want to call a different function without write if conditions like this:
if(a==1)
{
function1 ();
}
if(a==2)
{
function2 ();
}
if(a==3)
{
function3 ();
}
I want to call function like this :
Dictionary<int, function> functions= new Dictionary<int, function>();
functions.add(1, function1);functions.add(2, function2);functions.add(3, function3);
function[1];
How can I do this?
It seems your functions are actually actions, since a function returns a value. Also you don't have any method parameters, so you have to use Action.
Dictionary<int, Action> functions= new Dictionary<int, Action>();
functions.Add(1, function1);
functions.Add(2, function2);
functions.Add(3, function3);
function[1](); // <-- calling here needs parentheses
You can do something like the following
void Main()
{
Dictionary<int, Func<bool>> funcMap = new Dictionary<int, Func<bool>>() {
{1, Function1},
{2, Function2}
};
Console.WriteLine(funcMap[1]());
Console.WriteLine(funcMap[2]());
}
// Define other methods and classes here
bool Function1()
{
return true;
}
bool Function2()
{
return false;
}
This works because all functions have the same signature.
You can use lambdas to map functions with different signatures. Idea is the same as with Action:
var functions = new Dictionary<int, Action>
{
{ 1, () => method1(123) },
{ 2, () => method2(123, "123") },
};
functions[1](); // will call method1(123);
where functions are defined like this
void method1(int a) => Console.WriteLine(a);
void method2(int a, string b) => Console.WriteLine(a + b);
Related
With C#
I want to my delegate method into one dictionary, and put them all out and run.
for example
class class1{
Func<string,int> method1 = new Func<string,int>( x => 3);
Func<int,double> method2 = new Func<string,int>( x => 3.0);
Func<double,bool> method3 = new Func<string,int>( x => true);
Dictionary<string, dynamic> dic = new Dictionary<string, dynamic>();
dic.add("m1",method1)
dic.add("m2",method2)
dic.add("m3",method3)
// rund all method
dynamic RunMethod(Dictionary<string, dynamic> dic , dynamic firstInput, int index = 0)
{
if(index = dic.count) return
RunMethod(dic, dic.ElementAt[index].value(input) , index + 1)
}
void main ()
{
RunMethod( dix , "firstString" )
}
}
(this code has error but expression of what i want to do )
What i want to do is like below.
Create Method 1, 2 ,3
Output type of Method 1 = Input type of Method2 ,
Output type of Method 2 = Input type of Method3
Finally get output of Method3
There is Run Method that take Input that has type of method1 and method dictionary (or list or something)
I want to additional method that check what type of method 1? and output type of method 3
Not sure what are you exactly looking for. This code sample may help you.
class Class1
{
public Func<string, int> method1 = new Func<string, int>(x => 3);
public Func<int, double> method2 = new Func<int, double>(x => 4.0);
public Func<double, bool> method3 = new Func<double, bool>(x => true);
List<Delegate> methodList = new List<Delegate>();
public Class1()
{
methodList.Add(method1);
methodList.Add(method2);
methodList.Add(method3);
}
public object RunMethods(object param)
{
foreach(Delegate del in methodList)
{
param = del.DynamicInvoke(param);
}
return param;
}
}
static void Main(string[] args)
{
Class1 obj = new Class1();
object result = obj.RunMethods("some string");
}
I have a message coming into my C# app which is an object serialized as JSON, when i de-serialize it I have a "Name" string and a "Payload" string[], I want to be able to take the "Name" and look it up in a function dictionary, using the "Payload" array as its parameters and then take the output to return to the client sending the message, is this possible in C#?
I've found a stack overflow answer here where the second part seems plausible but i don't know what I'm referencing with State
It sounds like you probably want something like:
Dictionary<string, Func<string[], int>> functions = ...;
This is assuming the function returns an int (you haven't specified). So you'd call it like this:
int result = functions[name](parameters);
Or to validate the name:
Func<string[], int> function;
if (functions.TryGetValue(name, out function))
{
int result = function(parameters);
...
}
else
{
// No function with that name
}
It's not clear where you're trying to populate functions from, but if it's methods in the same class, you could have something like:
Dictionary<string, Func<string[], int>> functions =
new Dictionary<string, Func<string[], int>>
{
{ "Foo", CountParameters },
{ "Bar", SomeOtherMethodName }
};
...
private static int CountParameters(string[] parameters)
{
return parameters.Length;
}
// etc
You can create a dictionary of string as a key and a Action<string[]> as a value and use it, for sample:
var functions = new Dictionary<string, Action<string[]>>();
functions.Add("compute", (p) => { /* use p to compute something*/ });
functions.Add("load", (p) => { /* use p to compute something*/ });
functions.Add("process", (p) => { /* use p to process something*/ });
You could use it after you deserialize your message parameter, you could use the functions dictionary:
public void ProcessObject(MessageDTO message)
{
if (functions.ContainsKey(message.Name))
{
functions[name](message.Parameters);
}
}
Yes.
var functions = new Dictionary<string, Func<string[], string[]>>();
functions.Add("head", x => x.Take(1).ToArray());
functions.Add("tail", x => x.Skip(1).ToArray());
var result = functions["tail"](new [] {"a", "b", "c"});
Something similar to this:
public class Methods
{
public readonly Dictionary<string, Func<string[], object>> MethodsDict = new Dictionary<string, Func<string[], object>>();
public Methods()
{
MethodsDict.Add("Method1", Method1);
MethodsDict.Add("Method2", Method2);
}
public string Execute(string methodName, string[] strs)
{
Func<string[], object> method;
if (!MethodsDict.TryGetValue(methodName, out method))
{
// Not found;
throw new Exception();
}
object result = method(strs);
// Here you should serialize result with your JSON serializer
string json = result.ToString();
return json;
}
public object Method1(string[] strs)
{
return strs.Length;
}
public object Method2(string[] strs)
{
return string.Concat(strs);
}
}
Note that you could make it all static, if the methods don't need to access data from somewhere else.
The return type I chose for the delegates is object. In this way the Execute method can serialize it to Json freely.
My solution with input parameters, and a int as Key of Invoke:
private static Dictionary<int, Action> MethodDictionary(string param1, string param2, int param3) => new Dictionary<int, Action>
{
{1 , () => Method1(param1, param2, param3) },
{2 , () => Method2(param1, param2, param3) },
{3 , () => Method3(param1, param2, param3) },
{4 , () => Method4(param1, param2, param3) },
{5 , () => Method5(param1, param2, param3) }
};
And to invoke a method:
var methodDictionary = MethodDictionary("param1", "param2", 1);
methodDictionary[2].Invoke();
This will execute Method2.
Hope it helps!
Public void test(){
Console.WriteLine("Hello World");
}
Is it possible to save this method in a Dictionary, and call this method if Dicitionary contains the method's key value.
For example like this:
Hashtable table = new Hashtable<method, string>();
string input = "hello"
foreach(Dictionary.entry t in table){
if(input == t.Key){
//Call the t.value method.
}
}
class Program
{
private static void Main(string[] args)
{
var methods = new Dictionary<string, Action>();
//choose your poison:
methods["M1"] = MethodOne; //method reference
methods["M2"] = () => Console.WriteLine("Two"); //lambda expression
methods["M3"] = delegate { Console.WriteLine("Three"); }; //anonymous method
//call `em
foreach (var method in methods)
{
method.Value();
}
//or like tis
methods["M1"]();
}
static void MethodOne()
{
Console.WriteLine("One");
}
}
Yes, that's pretty easy: just use the Action delegate class:
Encapsulates a method that has no parameters and does not return a value.
var dict = new Dictionary<string, Action>();
dict.Add("hello", test);
var input = "hello";
dict[input]();
Demo
You can use Func to reference your methods and then call them in the loop
https://msdn.microsoft.com/en-us/library/bb549151%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396
And as #Lucas Trzesniewski answered your can use Action if your methods has no params
How can I define a function that expects another function that returns a bool in c#?
To clarify, this is what I'd like to do using C++:
void Execute(boost::function<int(void)> fctn)
{
if(fctn() != 0)
{
show_error();
}
}
int doSomething(int);
int doSomethingElse(int, string);
int main(int argc, char *argv[])
{
Execute(boost::bind(&doSomething, 12));
Execute(boost::bind(&doSomethingElse, 12, "Hello"));
}
In my example above the Execute function in combination is with the bind gets the expected result.
Background:
I've got a bunch of functions, each returning a int but with different parameter count that are surrounded by the same error checking code. A huge code duplication I want to avoid...
You can probably achieve what you want by using Func. For example
void Execute(Func<bool> myFunc)
{
if(myFunc() == false)
{
// Show error
}
}
You can then define your Func either as a method, or a lambda:
// Define a method
private bool MethodFunc() {}
// Pass in the method
Execute(MethodFunc)
// Pass in the Lambda
Execute(() => { return true; });
You don't nececssairly need to pass the parameters in as you can now access them from the caller's scope:
Execute(() => { return myBool; });
Execute(() => { return String.IsNullOrEmpty(myStr); });
With my solution, you can perform any function, any input parameter, with any return, this is a very generic implementation
Example:
public T YourMethod<T>(Func<T> functionParam)
{
return functionParam.Invoke();
}
public bool YourFunction(string foo, string bar, int intTest)
{
return true;
}
Call like This specifying the return :
YourMethod<bool>(() => YourFunction("bar", "foo", 1));
Or like this:
YourMethod(() => YourFunction("bar", "foo", 1));
without argument do this
void Execute(Func<bool> fctn)
{
if(fctn() )
{
show_error();
}
}
with arguments you can do something like this:
void Execute<T>(Func<T[],bool> fctn)
{
var v = new T[4];
if(fctn(v) )
{
show_error();
}
}
im trying to write some kind a strongly typed routing system.
Imagine ive got some class with method A that takes and returns string
public class SomeClass
{
public string MethodA(string str)
{
return string.Format("SomeClass :: MethodA {0}", str);
}
}
And I want my main method to look like this
class Program
{
static void Main(string[] args)
{
var col = new SomeCollection();
col.Add<SomeClass>("url", c => c.MethodA("test")); //Bind MethodA to "url"
}
}
So my questions are:
What should be Add method signature?
How can I invoke MethodA in SomeCollection?
I guess it'll be something like
public class SomeCollection
{
public void Add<TController> (string url, Func<TController, string> exp)
{
// Add func to dictionary <url, funcs>
}
public void FindBestMatchAndExecute (Request request)
{
//Search url in collection and invoke it's method.
//Method params we can extract from request.
}
}
First, I think you want add instances of classes to a collection, not the types. Otherwise, you will need to use reflection. If my assumption is correct, then instead of declaring Func<x,y,z,...> just employ Action to be able to call any method with any numbers of parameters.
Dictionary<object, Action> tempDictionary = new Dictionary<object, Action>();
SomeClass someClass = new SomeClass();
tempDictionary.Add(someClass, () => someClass.MethodA("test"));
tempDictionary.Single(q => q.Key == someClass).Value();
but if you need return values, you will have to use Func instead of Action;
Dictionary<object, Func<string>> tempDictionary = new Dictionary<object, Func<string>>();
SomeClass someClass = new SomeClass();
tempDictionary.Add(someClass, () => someClass.MethodA("test"));
string temp = tempDictionary.Single(q => q.Key == someClass).Value();