How to dynamically call a method in C#? [duplicate] - c#

This question already has answers here:
Calling a function from a string in C#
(5 answers)
Closed 1 year ago.
I have a method:
add(int x,int y)
I also have:
int a = 5;
int b = 6;
string s = "add";
Is it possible to call add(a,b) using the string s?

how can i do this in c#?
Using reflection.
add has to be a member of some type, so (cutting out a lot of detail):
typeof(MyType).GetMethod("add").Invoke(null, new [] {arg1, arg2})
This assumes add is static (otherwise first argument to Invoke is the object) and I don't need extra parameters to uniquely identify the method in the GetMethod call.

Use reflection - try the Type.GetMethod Method
Something like
MethodInfo addMethod = this.GetType().GetMethod("add");
object result = addMethod.Invoke(this, new object[] { x, y } );
You lose strong typing and compile-time checking - invoke doesn't know how many parameters the method expects, and what their types are and what the actual type of the return value is. So things could fail at runtime if you don't get it right.
It's also slower.

If the functions are known at compile time and you just want to avoid writing a switch statement.
Setup:
Dictionary<string, Func<int, int, int>> functions =
new Dictionary<string, Func<int, int, int>>();
functions["add"] = this.add;
functions["subtract"] = this.subtract;
Called by:
string functionName = "add";
int x = 1;
int y = 2;
int z = functions[functionName](x, y);

You can use reflection.
using System;
using System.Reflection;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Program p = new Program();
Type t = p.GetType();
MethodInfo mi = t.GetMethod("add", BindingFlags.NonPublic | BindingFlags.Instance);
string result = mi.Invoke(p, new object[] {4, 5}).ToString();
Console.WriteLine("Result = " + result);
Console.ReadLine();
}
private int add(int x, int y)
{
return x + y;
}
}
}

#Richard's answer is great. Just to expand it a bit:
This can be useful in a situation where you dynamically created an object of unknown type and need to call its method:
var do = xs.Deserialize(new XmlTextReader(ms)); // example - XML deserialization
do.GetType().GetMethod("myMethodName").Invoke(do, new [] {arg1, arg2});
becasue at compile time do is just an Object.

Related

How to wrap a Func<T1...Tn> with unknown number and type of parameters in C#?

Suppose I have this class:
public class Function {
public int argc; //number of arguments of the function
public float[] argv;
public Func<float> f; //attribute to store a function (e.g. Sin(x) or Pow(a, b))
}
I want to create instances of Function that hold different functions, like Sin(x) or Pow(a, b), but I don't know how to bind an existing function (with any number of arguments) to a Func. Obviously its declaration would not always be Func<float> but Func<float, float>, Func<float, float, float>, etc.
I've looked for Func, delegate, Action but still didn't figure out how to have this "function capsule" that can hold and execute functions with different number of arguments. For simplicity I consider the only input and output type is float.
I'm thinking about using something like Func<List<float>> but I want to know if there is a better option.
I want to suggest an answer that fits more accurately the scenario described by the OP. The key is in the usage of Delegate.DynamicInvoke which lets you pass an indefinite number of arguments to a delegate.
public class Function<TReturn> {
private readonly object[] _argv;
private readonly Delegate _func;
public Function(Delegate func, params object[] args) {
_func = func;
_argv = args;
}
public TReturn Run() {
object v = _func.DynamicInvoke(_argv);
return (TReturn)v;
}
}
And its usage lets you decide dynamically the number of arguments you wish to pass:
var s = new Function<double>((Func<double, double>)(x => Math.Sin(x)), 1 );
Console.WriteLine(s.Run()); // prints 0.8414709848078965
var p = new Function<double>((Func<double, double, double>)((a, b) => Math.Pow(a, b)), 2, 3);
Console.WriteLine(p.Run()); // prints 8
var d = new Function<string>((Func<string, double, string>)((a, b) => a + b.ToString()), "hello, ", 42);
Console.WriteLine(p.Run()); // prints "hello, 42"
Note that type checking is only performed at run-time when calling Function.Run() and not when constructing the Function object because of its dynamic nature. If you know for sure that all passed arguments will always be of the same type, you could enforce that statically by adding a TArg generic type.

C# - Delegate with any amount of custom parameters [duplicate]

This question already has answers here:
How can I design a class to receive a delegate having an unknown number of parameters?
(6 answers)
C# How to call a method with unknown number of parameters
(3 answers)
Closed 5 years ago.
I want a delegate that I can store in a variable for later use that has custom amounts of custom parameters. What I mean by that, is that I want to pus it different methods with different return types and different arguments. For example:
public double Sum (double a, double b) {return a + b;}
public char GetFirst (string a) {return a[0];}
public bool canFlipTable (object[] thingsOnIt) {return thingsOnIt.Length <= 3;}
DoTheThing<double> thing1 = new DoTheThing<double>(Sum);
DoTheThing<char> thing2 = new DoTheThing<char>(GetFirst);
DoTheThing<bool> thing3 = new DoTheThing<bool>(canFlipTable);
thing1.Call(10.3, 5.6); //15.9
thing2.Call("Hello World"); //'H'
thing3.Call(new object[] {new Lamp(), new Laptop(), new CoffeMug()}); //true
I figured out the return value and the call method already, but I'm having a problem with storing the methods
If I use "public DoTheThing(Action method)" it says, that the arguments doesn't match
I even tried with a delegate that had "params object[] p" as arguments, but it didn't work either
EDIT:
I forgot to tell, the method WILL always have a return type and at least 1 parameter
EDIT 2:
My goal is creating a wrapper class, that caches outputs from very expensive methods and if the same thing gets called again, it returns the cached value.
Of course I could solve this with an interface, but I want to do this with classes that I can't simply edit and I want to make this felxible too, so having the cache at the same place where I call the method is not an option either.
My code sofar:
public class DoTheThing <T>
{
public delegate T Method(params object[] parameters);
Func<T> method;
ParameterInfo[] pInfo;
public DoTheThing (Method method)
{
this.method = method;
Type type = typeof(Method);
MethodInfo info = type.GetMethod ("Invoke");
if (info.ReturnType != typeof(T)) {
throw new Exception ("Type of DoTheThing and method don't match");
}
pInfo = info.GetParameters ();
}
public T Call (params object[] parameters) {
if (parameters.Length != pInfo.Length) {
throw new Exception ("Wrong number of arguments, " + parameters.Length + " instead of " + pInfo.Length);
return default(T);
}
for (int i = 0; i < parameters.Length; i++) {
if (pInfo[i].ParameterType != parameters[i].GetType()) {
throw new Exception ("Wrong parameter: " + parameters [i].GetType () + " instead of " + pInfo [i].ParameterType + " at position: " + i);
return default(T);
}
}
return (T)method.DynamicInvoke (parameters);
}
}
Before trying to figure how to do it, I would really question the problem that leads me to have such a kind of delegate. I would bet if I knew the context better, there would be a solution that would eliminate your requirement.
Having that said, delegates are classes that inherit from MulticastDelegate. In fact, when you declare a delegate, you are creating a new class type with MulticastDelegate as its base class. That means the following code works:
public static double Sum(double a, double b)
{
return a + b;
}
public static string SayHello()
{
return "Hello";
}
static void Main(string[] args)
{
MulticastDelegate mydel = new Func<double, double, double>(Sum);
var ret = mydel.DynamicInvoke(1, 2);
System.Console.WriteLine(ret);
mydel = new Func<string>(SayHello);
ret = mydel.DynamicInvoke();
System.Console.WriteLine(ret);
mydel = new Func<string, int, string> ((s, i) => {
return $"Would be {s}, {i} times";
});
ret = mydel.DynamicInvoke("Hello", 5);
System.Console.WriteLine(ret);
}
Because "mydel" variable is of the base class type (MulticastDelegate), we can actually use it with any kind of delegate and invoke it with arbitrary parameters. If they don't match the method being invoked, it will throw at runtime.

How to use F# to process lists from C#

I'm trying to figure out how to use an F# library from a C# assembly, I have used C# quite a bit, but have never used F#.
Here is the F# Class..
namespace FLib
type Class1() =
member this.square(x)=x*x
member this.doit(x, op) = List.map op (Seq.toList(x))|>List.toSeq
member this.squareAllDirect(x) = List.map this.square (Seq.toList(x))|>List.toSeq
member this.squareAllIndirect(x) = this.doit x, this.square
Here is the C# using it
class Program
{
static void Main(string[] args)
{
FLib.Class1 f = new FLib.Class1();
List<int> l=new List<int>(){1,2,3,4,5};
var q =f.squareAllDirect(l);
var r = f.squareIndirect(l);
foreach (int i in r)
Console.Write("{0},",i);
Console.ReadKey();
}
}
The squareAllDirect function works as expected... but the squareAllIndirect call from c# has an exception:
The Type argument for method 'FLib.Class1.squareAllIndirect (System.Tuple,Microsoft.FSharp.Core.FSharpFunc'2>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
It looks you are expecting your squareAllIndirect function to take and returns a int seq
However if you mouse over it you will see it takes and returns a int seq * (int -> int)
Tuple is lower precedence than function call so x is passed as both arguments to doit.
You need to surround the parameters of your function call in ().
member this.squareAllIndirect(x) = this.doit(x, this.square)
That will ensure you take and return what you expect.

Passing an IEnumerable of Numeric Values as a parameter to method

I'm playing around with a very simple program to take an array of doubles and return the standard deviation. This part worked but I wanted to make the code more reusable. I would like to make it so the method can accept a parameter of any type that could be considered numeric and return the standard deviation instead of hardcoding a double type (like I initially did in this program). How does one go about this and what is the proper term for it?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication5
{
class Program
{
static void Main(string[] args)
{
double[] avg = { 3.4, 55.6, 10.0, 4.5, 2, 2 };
double x = avg.Average();
//first round of testing
Console.WriteLine("The average of the first array is below ");
Console.WriteLine(x);
Console.WriteLine("below should be the standard deviation!");
Console.WriteLine(CalculateStandardDeviation(avg));
Console.ReadLine();
int[] intAvg = { 4, 3, 5, 6, 2 };
double secondAvg = intAvg.Average();
Console.WriteLine("The average of the second array is below ");
Console.WriteLine(secondAvg);
//this is where the error is happening
//CalculateStandardDeviation(secondAvg);
}
//this is where I tried to make the query more reusable
public static double CalculateStandardDeviation(IEnumerable<double> values)
{
double avg = values.Average();
double sum = 0;
foreach (double d in values)
{
sum += Math.Pow((d - avg), 2);
}
return Math.Pow(sum / (values.Count() - 1),.5);
}
}
}
You could use something like this:
public static decimal CalculateStandardDeviation<T>(IEnumerable<T> values)
{
IEnumerable<decimal> decimalValues = values.Select(v => Convert.ToDecimal(v));
decimal result = 0;
// calculate standard deviation on decimalValues
return result;
}
It will throw an exception if values contains values that can't be converted to a decimal, but will work if the values are of an appropriate type, and I think that makes perfect sense.
Unfortunately, there is no base class for all numbers. You can do this with a generic run-time checking method, or a compile-time safe set of overloads.
Generic Method:
public static T CalculateStandardDeviation(IEnumerable<T> values)
{
var valueArray = values.Select(Convert.ToDecimal).ToArray();
//...
return (T)standardDeviation;
}
The problem with using a single generic method is that you can't put a type constraint on the type parameter that would restrict it to only numeric types. You would have to resort to failing at run-time. There would be nothing to stop you from calling the method with an array of strings, or objects, or Colors, or HttpWebRequests, etc. and unless you do in fact know how to calculate the standard deviation of a color, you should probably stick to individual overrides for a particular numeric type:
I would recommend using the decimal type as your main implementation, and then casting everything to it.
Type-Specific Overloads:
public static decimal CalculateStandardDeviation(IEnumerable<decimal> values)
{
//...
}
public static double CalculateStandardDeviation(IEnumerable<double> values)
{
return (double)CalculateStandardDeviation(values.Select(Convert.ToDecimal));
}
public static int CalculateStandardDeviation(IEnumerable<int> values)
{
return (int)CalculateStandardDeviation(values.Select(Convert.ToDecimal));
}
// etc...
Use C# Generics.
Your function signature will be:
public static T CalculateStandardDeviation(IEnumerable<T> values)
And you can use it like:
int stdDev = CalculateStandardDeviation([int-array]);
double stdDev = CalculateStandardDeviation([double-array]);
Please follow this link:
http://msdn.microsoft.com/en-us/library/ms379564%28VS.80%29.aspx
Edit:
To resolve the Average issue on the generic types, please take a look in this library:
How to Implement Generic Method to do Math calculations on different value types
Obs: Suggestion from Brian.
EDIT
You should use JLRishe's answer, it's much more elegant than this.
You should probably start by adding generics to your method and use the type converter to transform your unknown input into doubles like so :
public static double CalculateStandardDeviation<TSource>(IEnumerable<TSource> inputs)
{
var converter = TypeDescriptor.GetConverter(typeof (double));
if (!converter.CanConvertFrom(typeof(TSource)))
return 0;
var values = new List<double>();
foreach (var value in inputs)
{
values.Add((double) converter.ConvertFrom(value));
}
// Your logic here ...
return ...;
}
I did not tested this snippet but you get the idea.
Foreword:
this answer builds on
How to verify whether a type overloads/supports a certain operator?
and
http://www.codeproject.com/Articles/87438/TinyLisp-A-Language-and-Parser-to-See-LINQ-Express
The second link shows how to compile and evaluate linq expressions.
In short you could forego static type safety and check for the ability of a type to support specific operations at runtime (first link), in case it does not you could throw an exception as the following sample demonstrates:
void Main()
{
DoAdd<float>(5,6);
DoAdd<int>(5,6);
DoAdd<bool>(true,false);
}
// Define other methods and classes here
static void DoAdd<T>(T in1, T in2){
if(!HasAdd<T>()){throw new Exception("Unsupported Type!");}
var c1 = Expression.Constant(in1, typeof(T));
var c2 = Expression.Constant(in2, typeof(T));
var expression=Expression.Add(c1, c2);
Expression<Func<T>> lExpression = Expression.Lambda<Func<T>>(expression);
Func<T> fExpression = lExpression.Compile();
Console.WriteLine(fExpression());
}
static bool HasAdd<T>() {
var c = Expression.Constant(default(T), typeof(T));
try {
Expression.Add(c, c); // Throws an exception if + is not defined
return true;
} catch {
return false;
}
}
Passing an IEnumerable of Numeric Values as a parameter to method will be supported in C# 6.0

Closures and java anonymous inner classes

Would anyone be so kind to post the equivalent Java code for a closure like this one (obtained using C#) with anonymous inner classes?
public static Func<int, int> IncrementByN()
{
int n = 0; // n is local to the method
Func<int, int> increment = delegate(int x)
{
n++;
return x + n;
};
return increment;
}
static void Main(string[] args)
{
var v = IncrementByN();
Console.WriteLine(v(5)); // output 6
Console.WriteLine(v(6)); // output 8
}
Furthermore, can anyone explain how partial applications can be obtained if lexical closures are available and viceversa? For this second question, C# would be appreciated but it's your choice.
Thanks so much.
There is no closure yet in Java. Lambda expressions are coming in java 8. However, the only issue with what you're trying to translate is that it has state, which not something that lamba expressions will support i don't think. Keep in mind, it's really just a shorthand so that you can easily implement single method interfaces. You can however still simulate this I believe:
final AtomicInteger n = new AtomicInteger(0);
IncrementByN v = (int x) -> x + n.incrementAndGet();
System.out.println(v.increment(5));
System.out.println(v.increment(6));
I have not tested this code though, it's just meant as an example of what might possibly work in java 8.
Think of the collections api. Let's say they have this interface:
public interface CollectionMapper<S,T> {
public T map(S source);
}
And a method on java.util.Collection:
public interface Collection<K> {
public <T> Collection<T> map(CollectionMapper<K,T> mapper);
}
Now, let's see that without closures:
Collection<Long> mapped = coll.map(new CollectionMapper<Foo,Long>() {
public Long map(Foo foo) {
return foo.getLong();
}
}
Why not just write this:
Collection<Long> mapped = ...;
for (Foo foo : coll) {
mapped.add(foo.getLong());
}
Much more concise right?
Now introduce lambdas:
Collection<Long> mapped = coll.map( (Foo foo) -> foo.getLong() );
See how much nicer the syntax is? And you can chain it too (we'll assume there's an interface to do filtering which which returns boolean values to determine whether to filter out a value or not):
Collection<Long> mappedAndFiltered =
coll.map( (Foo foo) -> foo.getLong() )
.filter( (Long val) -> val.longValue() < 1000L );
This code is equivalent I believe (at least it produces the desired output):
public class Test {
static interface IncrementByN {
int increment(int x);
}
public static void main(String[] args) throws InterruptedException {
IncrementByN v = new IncrementByN() { //anonymous class
int n = 0;
#Override
public int increment(int x) {
n++;
return x + n;
}
};
System.out.println(v.increment(5)); // output 6
System.out.println(v.increment(6)); // output 8
}
}
Assuming we have a generic function interface:
public interface Func<A, B> {
B call A();
}
Then we can write it like this:
public class IncrementByN {
public static Func<Integer, Integer> IncrementByN()
{
final int n_outer = 0; // n is local to the method
Func<Integer, Integer> increment = new Func<Integer, Integer>() {
int n = n_outer; // capture it into a non-final instance variable
// we can really just write int n = 0; here
public Integer call(Integer x) {
n++;
return x + n;
}
};
return increment;
}
public static void main(String[] args) {
Func<Integer, Integer> v = IncrementByN();
System.out.println(v.call(5)); // output 6
System.out.println(v.call(6)); // output 8
}
}
Some notes:
In your program, you capture the variable n by reference from the enclosing scope, and can modify that variable from the closure. In Java, you can only capture final variables (thus capture is only by value).
What I did here is capture the final variable from the outside, and then assign it into a non-final instance variable inside the anonymous class. This allows "passing info" into the closure and at the same time having it be assignable inside the closure. However, this information flow only works "one way" -- changes to n inside the closure is not reflected in the enclosing scope. This is appropriate for this example because that local variable in the method is not used again after being captured by the closure.
If, instead, you want to be able to pass information "both ways", i.e. have the closure also be able to change things in the enclosing scope, and vice versa, you will need to instead capture a mutable data structure, like an array, and then make changes to elements inside that. That is uglier, and is rarer to need to do.

Categories