Related
How do I create a Dictionary where I can store functions?
Thanks.
I have about 30+ functions which can be executed from the user. I want to be able to execute the function this way:
private void functionName(arg1, arg2, arg3)
{
// code
}
dictionaryName.add("doSomething", functionName);
private void interceptCommand(string command)
{
foreach ( var cmd in dictionaryName )
{
if ( cmd.Key.Equals(command) )
{
cmd.Value.Invoke();
}
}
}
However, the function signature is not always the same, thus having different amount of arguments.
Like this:
Dictionary<int, Func<string, bool>>
This allows you to store functions that take a string parameter and return boolean.
dico[5] = foo => foo == "Bar";
Or if the function is not anonymous:
dico[5] = Foo;
where Foo is defined like this:
public bool Foo(string bar)
{
...
}
UPDATE:
After seeing your update it seems that you don't know in advance the signature of the function you would like to invoke. In .NET in order to invoke a function you need to pass all the arguments and if you don't know what the arguments are going to be the only way to achieve this is through reflection.
And here's another alternative:
class Program
{
static void Main()
{
// store
var dico = new Dictionary<int, Delegate>();
dico[1] = new Func<int, int, int>(Func1);
dico[2] = new Func<int, int, int, int>(Func2);
// and later invoke
var res = dico[1].DynamicInvoke(1, 2);
Console.WriteLine(res);
var res2 = dico[2].DynamicInvoke(1, 2, 3);
Console.WriteLine(res2);
}
public static int Func1(int arg1, int arg2)
{
return arg1 + arg2;
}
public static int Func2(int arg1, int arg2, int arg3)
{
return arg1 + arg2 + arg3;
}
}
With this approach you still need to know the number and type of parameters that need to be passed to each function at the corresponding index of the dictionary or you will get runtime error. And if your functions doesn't have return values use System.Action<> instead of System.Func<>.
However, the function signature is not
always the same, thus having different
amount of arguments.
Let's start with a few functions defined like this:
private object Function1() { return null; }
private object Function2(object arg1) { return null; }
private object Function3(object arg1, object arg3) { return null; }
You really have 2 viable options at your disposal:
1) Maintain type-safety by having clients call your function directly.
This is probably the best solution, unless you have very good reasons for breaking from this model.
When you talk about wanting to intercept function calls, it sounds to me like you're trying to re-invent virtual functions. There's a boat load of ways to get this sort of functionality out of the box, such as inheriting from a base class an overriding its functions.
It sounds to me like you want a class that's more of a wrapper than a derived instance of a base class, so do something like this:
public interface IMyObject
{
object Function1();
object Function2(object arg1);
object Function3(object arg1, object arg2);
}
class MyObject : IMyObject
{
public object Function1() { return null; }
public object Function2(object arg1) { return null; }
public object Function3(object arg1, object arg2) { return null; }
}
class MyObjectInterceptor : IMyObject
{
readonly IMyObject MyObject;
public MyObjectInterceptor()
: this(new MyObject())
{
}
public MyObjectInterceptor(IMyObject myObject)
{
MyObject = myObject;
}
public object Function1()
{
Console.WriteLine("Intercepted Function1");
return MyObject.Function1();
}
public object Function2(object arg1)
{
Console.WriteLine("Intercepted Function2");
return MyObject.Function2(arg1);
}
public object Function3(object arg1, object arg2)
{
Console.WriteLine("Intercepted Function3");
return MyObject.Function3(arg1, arg2);
}
}
2) OR map the input of your functions to a common interface.
This might work if all of your functions are related. For example, if you're writing a game, and all the functions do something to some part of the player or player's inventory. You'd end up with something like this:
class Interceptor
{
private object function1() { return null; }
private object function2(object arg1) { return null; }
private object function3(object arg1, object arg3) { return null; }
Dictionary<string, Func<State, object>> functions;
public Interceptor()
{
functions = new Dictionary<string, Func<State, object>>();
functions.Add("function1", state => function1());
functions.Add("function2", state => function2(state.arg1, state.arg2));
functions.Add("function3", state => function3(state.arg1, state.are2, state.arg3));
}
public object Invoke(string key, object state)
{
Func<object, object> func = functions[key];
return func(state);
}
}
Define the dictionary and add the function reference as the value, using System.Action as the type:
using System.Collections;
using System.Collections.Generic;
public class Actions {
public Dictionary<string, System.Action> myActions = new Dictionary<string, System.Action>();
public Actions() {
myActions ["myKey"] = TheFunction;
}
public void TheFunction() {
// your logic here
}
}
Then invoke it with:
Actions.myActions["myKey"]();
Hey, I hope this helps. What language are you coming from?
internal class ForExample
{
void DoItLikeThis()
{
var provider = new StringMethodProvider();
provider.Register("doSomethingAndGetGuid", args => DoSomeActionWithStringToGetGuid((string)args[0]));
provider.Register("thenUseItForSomething", args => DoSomeActionWithAGuid((Guid)args[0],(bool)args[1]));
Guid guid = provider.Intercept<Guid>("doSomethingAndGetGuid", "I don't matter except if I am null");
bool isEmpty = guid == default(Guid);
provider.Intercept("thenUseItForSomething", guid, isEmpty);
}
private void DoSomeActionWithAGuid(Guid id, bool isEmpty)
{
// code
}
private Guid DoSomeActionWithStringToGetGuid(string arg1)
{
if(arg1 == null)
{
return default(Guid);
}
return Guid.NewGuid();
}
}
public class StringMethodProvider
{
private readonly Dictionary<string, Func<object[], object>> _dictionary = new Dictionary<string, Func<object[], object>>();
public void Register<T>(string command, Func<object[],T> function)
{
_dictionary.Add(command, args => function(args));
}
public void Register(string command, Action<object[]> function)
{
_dictionary.Add(command, args =>
{
function.Invoke(args);
return null;
} );
}
public T Intercept<T>(string command, params object[] args)
{
return (T)_dictionary[command].Invoke(args);
}
public void Intercept(string command, params object[] args)
{
_dictionary[command].Invoke(args);
}
}
The following scenario would allow you to use a dictionary of elements to send in as input parameters and get the same as the output parameters.
First add the following line at the top:
using TFunc = System.Func<System.Collections.Generic.IDictionary<string, object>, System.Collections.Generic.IDictionary<string, object>>;
Then inside your class, define the dictionary as follows:
private Dictionary<String, TFunc> actions = new Dictionary<String, TFunc>(){
{"getmultipledata", (input) =>
{
//DO WORKING HERE
return null;
}
},
{"runproc", (input) =>
{
//DO WORKING HERE
return null;
}
}
};
This would allow you to run these anonymous functions with a syntax similar to this:
var output = actions["runproc"](inputparam);
Why not use params object[] list for method parameters and do some validation inside either your methods (or calling logic), It will allow for a variable number of parameters.
I have created an architecture in my C# code which does exactly what I want, but seems it would be very difficult to maintain in the long-run and am hoping there's a design pattern / better architecture I could be pointed towards.
I have created an object Test which, again, does exactly what I need perfectly which has the following structure:
class Test
{
public static Dictionary<string, Func<Test, object>> MethodDictionary;
public double Var1;
public double Var2;
private Lazy<object> _test1;
public object Test1 { get { return _test1.Value; } }
private Lazy<object> _test2;
public object Test2 { get { return _test2.Value; } }
public Test()
{
_test1 = new Lazy<object>(() => MethodDictionary["Test1"](this), true);
_test2 = new Lazy<object>(() => MethodDictionary["Test2"](this), true);
}
}
What this allows me to do is, at run-time to assign a dictionary of functions to my Test object and the 2 properties Test1 & Test2 will use the functions loaded into it to return values.
The implementation looking somewhat as follows:
class Program
{
static void Main(string[] args)
{
Dictionary<string, Func<Test, object>> MethodDictionary = new Dictionary<string,Func<Test,object>>();
MethodDictionary.Add("Test1", TestMethod1);
MethodDictionary.Add("Test2", TestMethod2);
Test.MethodDictionary = MethodDictionary;
var x = new Test() { Var1 = 20, Var2 = 30 };
Console.WriteLine(x.Test1.ToString());
Console.WriteLine(x.Test2.ToString());
Console.ReadKey();
}
private static object TestMethod1(Test t)
{ return t.Var1 + t.Var2; }
private static object TestMethod2(Test t)
{ return t.Var1 - t.Var2; }
}
And it works great and has proven very efficient for large sets of Test objects.
My challenge is that if I ever want to add in a new method to my Test class, I need to add in the:
private Lazy<object> _myNewMethod;
public object MyNewMethod { get { return _myNewMethod.Value; } }
Update the constuctor with the key to look for in the dictionary
And, although that is pretty simple, I'd love to have a 1-line add-in (maybe some form of custom object) or have the properties read directly form the dictionary without any need for defining them at all.
Any ideas? ANY help would be great!!!
Thanks!!!
One of the ways in which you could achieve your desired behavior, is to use something that resembles a miniature IoC framework for field injection, tuned to your specific use case.
To make things easier, allow less typing in your concrete classes and make things type-safe, we introduce the LazyField type:
public class LazyField<T>
{
private static readonly Lazy<T> Default = new Lazy<T>();
private readonly Lazy<T> _lazy;
public LazyField() : this(Default) { }
public LazyField(Lazy<T> lazy)
{
_lazy = lazy;
}
public override string ToString()
{
return _lazy.Value.ToString();
}
public static implicit operator T(LazyField<T> instance)
{
return instance._lazy.Value;
}
}
Furthermore, we define an abstract base class, that ensures that these fields will be created at construction time:
public abstract class AbstractLazyFieldHolder
{
protected AbstractLazyFieldHolder()
{
LazyFields.BuildUp(this); // ensures fields are populated.
}
}
Skipping for a moment how this is achieved (explained further below), this allows the following way of defining your Test class:
public class Test : AbstractLazyFieldHolder
{
public double Var1;
public double Var2;
public readonly LazyField<double> Test1;
public readonly LazyField<double> Test2;
}
Note that these fields are immutable, initialized in the constructor. Now, for your usage example, the below snippet shows the "new way" of doing this:
LazyFields.Configure<Test>()
// We can use a type-safe lambda
.SetProvider(x => x.Test1, inst => inst.Var1 + inst.Var2)
// Or the field name.
.SetProvider("Test2", TestMethod2);
var x = new Test() { Var1 = 20, Var2 = 30 };
Console.WriteLine(x.Test1);
double test2Val = x.Test2; // type-safe conversion
Console.WriteLine(test2Val);
// Output:
// 50
// -10
The class below provides the services that support the configuration and injection of these field value.
public static class LazyFields
{
private static readonly ConcurrentDictionary<Type, IBuildUp> _registry = new ConcurrentDictionary<Type,IBuildUp>();
public interface IConfigureType<T> where T : class
{
IConfigureType<T> SetProvider<FT>(string fieldName, Func<T, FT> provider);
IConfigureType<T> SetProvider<F, FT>(Expression<Func<T, F>> fieldExpression, Func<T, FT> provider) where F : LazyField<FT>;
}
public static void BuildUp(object instance)
{
System.Diagnostics.Debug.Assert(instance != null);
var builder = _registry.GetOrAdd(instance.GetType(), BuildInitializer);
builder.BuildUp(instance);
}
public static IConfigureType<T> Configure<T>() where T : class
{
return (IConfigureType<T>)_registry.GetOrAdd(typeof(T), BuildInitializer);
}
private interface IBuildUp
{
void BuildUp(object instance);
}
private class TypeCfg<T> : IBuildUp, IConfigureType<T> where T : class
{
private readonly List<FieldInfo> _fields;
private readonly Dictionary<string, Action<T>> _initializers;
public TypeCfg()
{
_fields = typeof(T)
.GetFields(BindingFlags.Instance | BindingFlags.Public)
.Where(IsLazyField)
.ToList();
_initializers = _fields.ToDictionary(x => x.Name, BuildDefaultSetter);
}
public IConfigureType<T> SetProvider<FT>(string fieldName, Func<T,FT> provider)
{
var pi = _fields.First(x => x.Name == fieldName);
_initializers[fieldName] = BuildSetter<FT>(pi, provider);
return this;
}
public IConfigureType<T> SetProvider<F,FT>(Expression<Func<T,F>> fieldExpression, Func<T,FT> provider)
where F : LazyField<FT>
{
return SetProvider((fieldExpression.Body as MemberExpression).Member.Name, provider);
}
public void BuildUp(object instance)
{
var typedInstance = (T)instance;
foreach (var initializer in _initializers.Values)
initializer(typedInstance);
}
private bool IsLazyField(FieldInfo fi)
{
return fi.FieldType.IsGenericType && fi.FieldType.GetGenericTypeDefinition() == typeof(LazyField<>);
}
private Action<T> BuildDefaultSetter(FieldInfo fi)
{
var itemType = fi.FieldType.GetGenericArguments()[0];
var defValue = Activator.CreateInstance(typeof(LazyField<>).MakeGenericType(itemType));
return (inst) => fi.SetValue(inst, defValue);
}
private Action<T> BuildSetter<FT>(FieldInfo fi, Func<T, FT> provider)
{
return (inst) => fi.SetValue(inst, new LazyField<FT>(new Lazy<FT>(() => provider(inst))));
}
}
private static IBuildUp BuildInitializer(Type targetType)
{
return (IBuildUp)Activator.CreateInstance(typeof(TypeCfg<>).MakeGenericType(targetType));
}
}
Look at library https://github.com/ekonbenefits/impromptu-interface.
With it and using DynamicObject i wrote sample code that shows how to simplify adding new methods:
public class Methods
{
public Methods()
{
MethodDictionary = new Dictionary<string, Func<ITest, object>>();
LazyObjects = new Dictionary<string, Lazy<object>>();
}
public Dictionary<string, Func<ITest, object>> MethodDictionary { get; private set; }
public Dictionary<string, Lazy<object>> LazyObjects { get; private set; }
}
public class Proxy : DynamicObject
{
Methods _methods;
public Proxy()
{
_methods = new Methods();
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
result = _methods.LazyObjects[binder.Name].Value;
return true;
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
_methods.MethodDictionary[binder.Name] = (Func<ITest, object>)value;
_methods.LazyObjects[binder.Name] = new Lazy<object>(() => _methods.MethodDictionary[binder.Name](this.ActLike<ITest>()), true);
return true;
}
}
//now you can add new methods by add single method to interface
public interface ITest
{
object Test1 { get; set; }
object Test2 { get; set; }
}
class Program
{
static void Main(string[] args)
{
var x = new Proxy().ActLike<ITest>();
x.Test1 = new Func<ITest, object>((y) => "Test1");
x.Test2 = new Func<ITest, object>((y) => "Test2");
Console.WriteLine(x.Test1);
Console.WriteLine(x.Test2);
}
}
I don't know what you are trying to do, but I think you can use a simpler approach like this:
class Test
{
public static Dictionary<string, Func<Test, object>> MethodDictionary;
public double Var1;
public double Var2;
}
Calling the function is simple:
static void Main(string[] args)
{
Dictionary<string, Func<Test, object>> MethodDictionary = new Dictionary<string,Func<Test,object>>();
MethodDictionary.Add("Test1", TestMethod1);
MethodDictionary.Add("Test2", TestMethod2);
Test.MethodDictionary = MethodDictionary;
var x = new Test() { Var1 = 20, Var2 = 30 };
Console.WriteLine(Test.MethodDictionary["Test1"](x).ToString());
Console.WriteLine(Test.MethodDictionary["Test2"](x).ToString());
Console.ReadKey();
}
I've got a class, which has three overloaded methods. Let's say, there is:
class MyChildClass
{
public void myMethod(int i)
{ /* do something with i */ }
public void myMethod(int a, string b)
{ /* get i from a and b and call: */ myMethod(i); }
public void myMethod(string c, string d)
{ /* get i from c and d and call: */ myMethod(i); }
}
Now I'd like this class to be a private field in other (parent) class, but I need those three methods to be accessible. For now, I just did:
class MyBaseClass
{
private MyChildClass myObject = new myChildClass(); // or similar
public void myMethod(int i)
{ myObject.myMethod(i); }
public void myMethod(int a, string b)
{ myObject.myMethod(a, b); }
public void myMethod(string c, string s)
{ myObject.myMethod(c, d); }
}
Is there a way to implement it as one short method? Something which would look like:
public void myMethod(unknownListOfArgumentsOfDifferentTypes args)
{ myObject.myMethod(args); }
I tried to use public void myMethod(params object[] something) but it didn't work. Is it possible, or do I have to "project" every method into another?
EDIT: Child class has various methods and fields, which I want to be accessible for parent class only. That's why I don't want parent to derive after it. I didn't explain that, sorry if it looked like child class contains only those three methods. Those are the methods I want to be accessible as public methods of parent class.
Why don't you do
class MyChildClass : MyBaseClass
{
}
same effect, less code, and this way MyChildClass is a MyBaseClass
If you implement some sort of generic facade using reflection you'll just be reducing performance, bypassing the benefits of type safety and delaying the discovery of problems.
You'll also have have a "has a" relationship instead "is a" relationship which is incongruent with your class names.
If you want to give up this simplicty with its associated benefits you could make use the GetMethodBySig extension accepted in this post.
Something like this,
class SemiGenericFacade<T> where T : new()
{
private readonly t = new T();
public void CallVoidOnT(string name, params object[] parameters)
{
var paramTypes = parameters.Select(p => typeof(p))
var match = typeof(T).GetMethodBySig(typeof(void), paramTypes)
.Single(mi => mi.Name == name);
match.Invoke(this.t, parameters);
}
}
Following on from Piotr Justyna's comment, implementing and using this method results in the cat turning into a tiger and eating her kittens.
If you were to do this it would make sense to add to the linked extension
public static class Extensions
{
public static MethodInfo GetMethodByNameThenSig(
this Type type,
string name,
Type returnType,
params Type[] parameterTypes)
{
return type.GetMethods().Where((m) =>
{
if (m.Name != name)
{
return false;
}
if (m.ReturnType != returnType)
{
return false;
}
var parameters = m.GetParameters();
if ((parameterTypes == null || parameterTypes.Length == 0))
{
return parameters.Length == 0;
}
if (parameters.Length != parameterTypes.Length)
{
return false;
}
for (int i = 0; i < parameterTypes.Length; i++)
{
if (parameters[i].ParameterType != parameterTypes[i])
{
return false;
}
}
return true;
}).Single();
}
}
Which you could use like this,
class GenericFacade<T> where T : new()
{
private readonly t = new T();
public void CallOnInternal(string name, params object[] parameters)
{
var paramTypes = parameters.Select(p => typeof(p))
var match = typeof(T).GetMethodByNameThenSig(
name,
typeof(void),
paramTypes);
match.Invoke(this.t, parameters);
}
public TResult CallOnInternal<TResult>(string name, params object[] parameters)
{
var paramTypes = parameters.Select(p => typeof(p))
var match = typeof(T).GetMethodByNameThenSig(
name,
typeof(TResult),
paramTypes);
return (TResult)match.Invoke(this.t, parameters);
}
}
FINAL EDIT
Looking at the code involved to use reflection and considering the cost associated with the loss of type safety. I'd suggest its better to establish the "has-a" relationship explicitly in the traditional manner.
You can use public void myMethod(params object[] something) as in:
public static void Main()
{
UnknownArgumentsMethod1(1, 2, 3, "foo");
}
public static void UnknownArgumentsMethod1(params object[] list)
{
UnknownArgumentsMethod2(list);
}
public static void UnknownArgumentsMethod2(params object[] list)
{
foreach (object o in list)
{
if (o.GetType() == typeof(int))
{
Console.WriteLine("This is an integer: " + (int)o);
}
else if (o.GetType() == typeof(string))
{
Console.WriteLine("This is a string: " + (string)o);
}
}
}
The obvious answer would be to have inheritance.
In your case (even though the names of the classes suggest otherwise) the way to do it is by inheriting the ChildClass in the BaseClass and that way you would have the methods from the ChildClass exposed through the BaseClass.
ex:
class MyBaseClass: MyChildClass
{
}
If the classes are not related and you just want to have an instance of MyChildClass in MyBaseClass but only expose a certain set of methods but by not making the others private what you could do is expose the MyChildClass instance through an interface that only exposes the necessary fields like so:
public class BaseClass
{
public IChildClass ChildClassInstance = new ChildClass();
}
public class ChildClass : IChildClass
{
public void myMethod(int i)
{ /* do something with i */ }
public void myMethod(int a, string b)
{ /* get i from a and b and call: */ myMethod(i); }
public void myMethod(string c, string d)
{ /* get i from c and d and call: */ myMethod(i); }
}
public interface IChildClass
{
void myMethod(int i);
void myMethod(int a, string b);
}
and then you could access only the methods that you allow to be exposed through an instance of the base class:
BaseClass test = new BaseClass();
test.ChildClassInstance.myMethod(1);
test.ChildClassInstance.myMethod(1,"test");
Is there a well-known way for simulating the variadic template feature in C#?
For instance, I'd like to write a method that takes a lambda with an arbitrary set of parameters. Here is in pseudo code what I'd like to have:
void MyMethod<T1,T2,...,TReturn>(Fun<T1,T2, ..., TReturn> f)
{
}
C# generics are not the same as C++ templates. C++ templates are expanded compiletime and can be used recursively with variadic template arguments. The C++ template expansion is actually Turing Complete, so there is no theoretically limit to what can be done in templates.
C# generics are compiled directly, with an empty "placeholder" for the type that will be used at runtime.
To accept a lambda taking any number of arguments you would either have to generate a lot of overloads (through a code generator) or accept a LambdaExpression.
There is no varadic support for generic type arguments (on either methods or types). You will have to add lots of overloads.
varadic support is only available for arrays, via params, i.e.
void Foo(string key, params int[] values) {...}
Improtantly - how would you even refer to those various T* to write a generic method? Perhaps your best option is to take a Type[] or similar (depending on the context).
I know this is an old question, but if all you want to do is something simple like print those types out, you can do this very easily without Tuple or anything extra using 'dynamic':
private static void PrintTypes(params dynamic[] args)
{
foreach (var arg in args)
{
Console.WriteLine(arg.GetType());
}
}
static void Main(string[] args)
{
PrintTypes(1,1.0,"hello");
Console.ReadKey();
}
Will print "System.Int32" , "System.Double", "System.String"
If you want to perform some action on these things, as far as I know you have two choices. One is to trust the programmer that these types can do a compatible action, for example if you wanted to make a method to Sum any number of parameters. You could write a method like the following saying how you want to receive the result and the only prerequisite I guess would be that the + operation works between these types:
private static void AddToFirst<T>(ref T first, params dynamic[] args)
{
foreach (var arg in args)
{
first += arg;
}
}
static void Main(string[] args)
{
int x = 0;
AddToFirst(ref x,1,1.5,2.0,3.5,2);
Console.WriteLine(x);
double y = 0;
AddToFirst(ref y, 1, 1.5, 2.0, 3.5, 2);
Console.WriteLine(y);
Console.ReadKey();
}
With this, the output for the first line would be "9" because adding to an int, and the second line would be "10" because the .5s didn't get rounded, adding as a double. The problem with this code is if you pass some incompatible type in the list, it will have an error because the types can't get added together, and you won't see that error at compile time, only at runtime.
So, depending on your use case there might be another option which is why I said there were two choices at first. Assuming you know the choices for the possible types, you could make an interface or abstract class and make all of those types implement the interface. For example, the following. Sorry this is a bit crazy. And it can probably be simplfied.
public interface Applyable<T>
{
void Apply(T input);
T GetValue();
}
public abstract class Convertable<T>
{
public dynamic value { get; set; }
public Convertable(dynamic value)
{
this.value = value;
}
public abstract T GetConvertedValue();
}
public class IntableInt : Convertable<int>, Applyable<int>
{
public IntableInt(int value) : base(value) {}
public override int GetConvertedValue()
{
return value;
}
public void Apply(int input)
{
value += input;
}
public int GetValue()
{
return value;
}
}
public class IntableDouble : Convertable<int>
{
public IntableDouble(double value) : base(value) {}
public override int GetConvertedValue()
{
return (int) value;
}
}
public class IntableString : Convertable<int>
{
public IntableString(string value) : base(value) {}
public override int GetConvertedValue()
{
// If it can't be parsed return zero
int result;
return int.TryParse(value, out result) ? result : 0;
}
}
private static void ApplyToFirst<TResult>(ref Applyable<TResult> first, params Convertable<TResult>[] args)
{
foreach (var arg in args)
{
first.Apply(arg.GetConvertedValue());
}
}
static void Main(string[] args)
{
Applyable<int> result = new IntableInt(0);
IntableInt myInt = new IntableInt(1);
IntableDouble myDouble1 = new IntableDouble(1.5);
IntableDouble myDouble2 = new IntableDouble(2.0);
IntableDouble myDouble3 = new IntableDouble(3.5);
IntableString myString = new IntableString("2");
ApplyToFirst(ref result, myInt, myDouble1, myDouble2, myDouble3, myString);
Console.WriteLine(result.GetValue());
Console.ReadKey();
}
Will output "9" the same as the original Int code, except the only values you can actually pass in as parameters are things that you actually have defined and you know will work and not cause any errors. Of course, you would have to make new classes i.e. DoubleableInt , DoubleableString, etc.. in order to re-create the 2nd result of 10. But this is just an example, so you wouldn't even be trying to add things at all depending on what code you are writing and you would just start out with the implementation that served you the best.
Hopefully someone can improve on what I wrote here or use it to see how this can be done in C#.
Another alternative besides those mentioned above is to use Tuple<,> and reflection, for example:
class PrintVariadic<T>
{
public T Value { get; set; }
public void Print()
{
InnerPrint(Value);
}
static void InnerPrint<Tn>(Tn t)
{
var type = t.GetType();
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Tuple<,>))
{
var i1 = type.GetProperty("Item1").GetValue(t, new object[]{});
var i2 = type.GetProperty("Item2").GetValue(t, new object[]{ });
InnerPrint(i1);
InnerPrint(i2);
return;
}
Console.WriteLine(t.GetType());
}
}
class Program
{
static void Main(string[] args)
{
var v = new PrintVariadic<Tuple<
int, Tuple<
string, Tuple<
double,
long>>>>();
v.Value = Tuple.Create(
1, Tuple.Create(
"s", Tuple.Create(
4.0,
4L)));
v.Print();
Console.ReadKey();
}
}
I don't necessarily know if there's a name for this pattern, but I arrived at the following formulation for a recursive generic interface that allows an unlimited amount of values to be passed in, with the returned type retaining type information for all passed values.
public interface ITraversalRoot<TRoot>
{
ITraversalSpecification<TRoot> Specify();
}
public interface ITraverser<TRoot, TCurrent>: ITraversalRoot<TRoot>
{
IDerivedTraverser<TRoot, TInclude, TCurrent, ITraverser<TRoot, TCurrent>> AndInclude<TInclude>(Expression<Func<TCurrent, TInclude>> path);
}
public interface IDerivedTraverser<TRoot, TDerived, TParent, out TParentTraverser> : ITraverser<TRoot, TParent>
{
IDerivedTraverser<TRoot, TInclude, TDerived, IDerivedTraverser<TRoot, TDerived, TParent, TParentTraverser>> FromWhichInclude<TInclude>(Expression<Func<TDerived, TInclude>> path);
TParentTraverser ThenBackToParent();
}
There's no casting or "cheating" of the type system involved here: you can keep stacking on more values and the inferred return type keeps storing more and more information. Here is what the usage looks like:
var spec = Traversal
.StartFrom<VirtualMachine>() // ITraverser<VirtualMachine, VirtualMachine>
.AndInclude(vm => vm.EnvironmentBrowser) // IDerivedTraverser<VirtualMachine, EnvironmentBrowser, VirtualMachine, ITraverser<VirtualMachine, VirtualMachine>>
.AndInclude(vm => vm.Datastore) // IDerivedTraverser<VirtualMachine, Datastore, VirtualMachine, ITraverser<VirtualMachine, VirtualMachine>>
.FromWhichInclude(ds => ds.Browser) // IDerivedTraverser<VirtualMachine, HostDatastoreBrowser, Datastore, IDerivedTraverser<VirtualMachine, Datastore, VirtualMachine, ITraverser<VirtualMachine, VirtualMachine>>>
.FromWhichInclude(br => br.Mountpoints) // IDerivedTraverser<VirtualMachine, Mountpoint, HostDatastoreBrowser, IDerivedTraverser<VirtualMachine, HostDatastoreBrowser, Datastore, IDerivedTraverser<VirtualMachine, Datastore, VirtualMachine, ITraverser<VirtualMachine, VirtualMachine>>>>
.Specify(); // ITraversalSpecification<VirtualMachine>
As you can see the type signature becomes basically unreadable near after a few chained calls, but this is fine so long as type inference works and suggests the right type to the user.
In my example I am dealing with Funcs arguments, but you could presumably adapt this code to deal with arguments of arbitrary type.
For a simulation you can say:
void MyMethod<TSource, TResult>(Func<TSource, TResult> f) where TSource : Tparams {
where Tparams to be a variadic arguments implementation class. However, the framework does not provide an out-of-box stuff to do that, Action, Func, Tuple, etc., are all have limited length of their signatures. The only thing I can think of is to apply the CRTP .. in a way I've not find somebody blogged. Here's my implementation:
*: Thank #SLaks for mentioning Tuple<T1, ..., T7, TRest> also works in a recursive way. I noticed it's recursive on the constructor and the factory method instead of its class definition; and do a runtime type checking of the last argument of type TRest is required to be a ITupleInternal; and this works a bit differently.
Code
using System;
namespace VariadicGenerics {
public interface INode {
INode Next {
get;
}
}
public interface INode<R>:INode {
R Value {
get; set;
}
}
public abstract class Tparams {
public static C<TValue> V<TValue>(TValue x) {
return new T<TValue>(x);
}
}
public class T<P>:C<P> {
public T(P x) : base(x) {
}
}
public abstract class C<R>:Tparams, INode<R> {
public class T<P>:C<T<P>>, INode<P> {
public T(C<R> node, P x) {
if(node is R) {
Next=(R)(node as object);
}
else {
Next=(node as INode<R>).Value;
}
Value=x;
}
public T() {
if(Extensions.TypeIs(typeof(R), typeof(C<>.T<>))) {
Next=(R)Activator.CreateInstance(typeof(R));
}
}
public R Next {
private set;
get;
}
public P Value {
get; set;
}
INode INode.Next {
get {
return this.Next as INode;
}
}
}
public new T<TValue> V<TValue>(TValue x) {
return new T<TValue>(this, x);
}
public int GetLength() {
return m_expandedArguments.Length;
}
public C(R x) {
(this as INode<R>).Value=x;
}
C() {
}
static C() {
m_expandedArguments=Extensions.GetExpandedGenericArguments(typeof(R));
}
// demonstration of non-recursive traversal
public INode this[int index] {
get {
var count = m_expandedArguments.Length;
for(INode node = this; null!=node; node=node.Next) {
if(--count==index) {
return node;
}
}
throw new ArgumentOutOfRangeException("index");
}
}
R INode<R>.Value {
get; set;
}
INode INode.Next {
get {
return null;
}
}
static readonly Type[] m_expandedArguments;
}
}
Note the type parameter for the inherited class C<> in the declaration of
public class T<P>:C<T<P>>, INode<P> {
is T<P>, and the class T<P> is nested so that you can do some crazy things such as:
Test
[Microsoft.VisualStudio.TestTools.UnitTesting.TestClass]
public class TestClass {
void MyMethod<TSource, TResult>(Func<TSource, TResult> f) where TSource : Tparams {
T<byte>.T<char>.T<uint>.T<long>.
T<byte>.T<char>.T<long>.T<uint>.
T<byte>.T<long>.T<char>.T<uint>.
T<long>.T<byte>.T<char>.T<uint>.
T<long>.T<byte>.T<uint>.T<char>.
T<byte>.T<long>.T<uint>.T<char>.
T<byte>.T<uint>.T<long>.T<char>.
T<byte>.T<uint>.T<char>.T<long>.
T<uint>.T<byte>.T<char>.T<long>.
T<uint>.T<byte>.T<long>.T<char>.
T<uint>.T<long>.T<byte>.T<char>.
T<long>.T<uint>.T<byte>.T<char>.
T<long>.T<uint>.T<char>.T<byte>.
T<uint>.T<long>.T<char>.T<byte>.
T<uint>.T<char>.T<long>.T<byte>.
T<uint>.T<char>.T<byte>.T<long>.
T<char>.T<uint>.T<byte>.T<long>.
T<char>.T<uint>.T<long>.T<byte>.
T<char>.T<long>.T<uint>.T<byte>.
T<long>.T<char>.T<uint>.T<byte>.
T<long>.T<char>.T<byte>.T<uint>.
T<char>.T<long>.T<byte>.T<uint>.
T<char>.T<byte>.T<long>.T<uint>.
T<char>.T<byte>.T<uint>.T<long>
crazy = Tparams
// trying to change any value to not match the
// declaring type makes the compilation fail
.V((byte)1).V('2').V(4u).V(8L)
.V((byte)1).V('2').V(8L).V(4u)
.V((byte)1).V(8L).V('2').V(4u)
.V(8L).V((byte)1).V('2').V(4u)
.V(8L).V((byte)1).V(4u).V('2')
.V((byte)1).V(8L).V(4u).V('2')
.V((byte)1).V(4u).V(8L).V('2')
.V((byte)1).V(4u).V('2').V(8L)
.V(4u).V((byte)1).V('2').V(8L)
.V(4u).V((byte)1).V(8L).V('2')
.V(4u).V(8L).V((byte)1).V('2')
.V(8L).V(4u).V((byte)1).V('2')
.V(8L).V(4u).V('9').V((byte)1)
.V(4u).V(8L).V('2').V((byte)1)
.V(4u).V('2').V(8L).V((byte)1)
.V(4u).V('2').V((byte)1).V(8L)
.V('2').V(4u).V((byte)1).V(8L)
.V('2').V(4u).V(8L).V((byte)1)
.V('2').V(8L).V(4u).V((byte)1)
.V(8L).V('2').V(4u).V((byte)1)
.V(8L).V('2').V((byte)1).V(4u)
.V('2').V(8L).V((byte)1).V(4u)
.V('2').V((byte)1).V(8L).V(4u)
.V('7').V((byte)1).V(4u).V(8L);
var args = crazy as TSource;
if(null!=args) {
f(args);
}
}
[TestMethod]
public void TestMethod() {
Func<
T<byte>.T<char>.T<uint>.T<long>.
T<byte>.T<char>.T<long>.T<uint>.
T<byte>.T<long>.T<char>.T<uint>.
T<long>.T<byte>.T<char>.T<uint>.
T<long>.T<byte>.T<uint>.T<char>.
T<byte>.T<long>.T<uint>.T<char>.
T<byte>.T<uint>.T<long>.T<char>.
T<byte>.T<uint>.T<char>.T<long>.
T<uint>.T<byte>.T<char>.T<long>.
T<uint>.T<byte>.T<long>.T<char>.
T<uint>.T<long>.T<byte>.T<char>.
T<long>.T<uint>.T<byte>.T<char>.
T<long>.T<uint>.T<char>.T<byte>.
T<uint>.T<long>.T<char>.T<byte>.
T<uint>.T<char>.T<long>.T<byte>.
T<uint>.T<char>.T<byte>.T<long>.
T<char>.T<uint>.T<byte>.T<long>.
T<char>.T<uint>.T<long>.T<byte>.
T<char>.T<long>.T<uint>.T<byte>.
T<long>.T<char>.T<uint>.T<byte>.
T<long>.T<char>.T<byte>.T<uint>.
T<char>.T<long>.T<byte>.T<uint>.
T<char>.T<byte>.T<long>.T<uint>.
T<char>.T<byte>.T<uint>.T<long>, String>
f = args => {
Debug.WriteLine(String.Format("Length={0}", args.GetLength()));
// print fourth value from the last
Debug.WriteLine(String.Format("value={0}", args.Next.Next.Next.Value));
args.Next.Next.Next.Value='x';
Debug.WriteLine(String.Format("value={0}", args.Next.Next.Next.Value));
return "test";
};
MyMethod(f);
}
}
Another thing to note is we have two classes named T, the non-nested T:
public class T<P>:C<P> {
is just for the consistency of usage, and I made class C abstract to not directly being newed.
The Code part above needs to expand ther generic argument to calculate about their length, here are two extension methods it used:
Code(extensions)
using System.Diagnostics;
using System;
namespace VariadicGenerics {
[DebuggerStepThrough]
public static class Extensions {
public static readonly Type VariadicType = typeof(C<>.T<>);
public static bool TypeIs(this Type x, Type d) {
if(null==d) {
return false;
}
for(var c = x; null!=c; c=c.BaseType) {
var a = c.GetInterfaces();
for(var i = a.Length; i-->=0;) {
var t = i<0 ? c : a[i];
if(t==d||t.IsGenericType&&t.GetGenericTypeDefinition()==d) {
return true;
}
}
}
return false;
}
public static Type[] GetExpandedGenericArguments(this Type t) {
var expanded = new Type[] { };
for(var skip = 1; t.TypeIs(VariadicType) ? true : skip-->0;) {
var args = skip>0 ? t.GetGenericArguments() : new[] { t };
if(args.Length>0) {
var length = args.Length-skip;
var temp = new Type[length+expanded.Length];
Array.Copy(args, skip, temp, 0, length);
Array.Copy(expanded, 0, temp, length, expanded.Length);
expanded=temp;
t=args[0];
}
}
return expanded;
}
}
}
For this implementation, I choosed not to break the compile-time type checking, so we do not have a constructor or a factory with the signature like params object[] to provide values; instead, use a fluent pattern of method V for mass object instantiation to keep type can be statically type checked as much as possible.
How do I create a Dictionary where I can store functions?
Thanks.
I have about 30+ functions which can be executed from the user. I want to be able to execute the function this way:
private void functionName(arg1, arg2, arg3)
{
// code
}
dictionaryName.add("doSomething", functionName);
private void interceptCommand(string command)
{
foreach ( var cmd in dictionaryName )
{
if ( cmd.Key.Equals(command) )
{
cmd.Value.Invoke();
}
}
}
However, the function signature is not always the same, thus having different amount of arguments.
Like this:
Dictionary<int, Func<string, bool>>
This allows you to store functions that take a string parameter and return boolean.
dico[5] = foo => foo == "Bar";
Or if the function is not anonymous:
dico[5] = Foo;
where Foo is defined like this:
public bool Foo(string bar)
{
...
}
UPDATE:
After seeing your update it seems that you don't know in advance the signature of the function you would like to invoke. In .NET in order to invoke a function you need to pass all the arguments and if you don't know what the arguments are going to be the only way to achieve this is through reflection.
And here's another alternative:
class Program
{
static void Main()
{
// store
var dico = new Dictionary<int, Delegate>();
dico[1] = new Func<int, int, int>(Func1);
dico[2] = new Func<int, int, int, int>(Func2);
// and later invoke
var res = dico[1].DynamicInvoke(1, 2);
Console.WriteLine(res);
var res2 = dico[2].DynamicInvoke(1, 2, 3);
Console.WriteLine(res2);
}
public static int Func1(int arg1, int arg2)
{
return arg1 + arg2;
}
public static int Func2(int arg1, int arg2, int arg3)
{
return arg1 + arg2 + arg3;
}
}
With this approach you still need to know the number and type of parameters that need to be passed to each function at the corresponding index of the dictionary or you will get runtime error. And if your functions doesn't have return values use System.Action<> instead of System.Func<>.
However, the function signature is not
always the same, thus having different
amount of arguments.
Let's start with a few functions defined like this:
private object Function1() { return null; }
private object Function2(object arg1) { return null; }
private object Function3(object arg1, object arg3) { return null; }
You really have 2 viable options at your disposal:
1) Maintain type-safety by having clients call your function directly.
This is probably the best solution, unless you have very good reasons for breaking from this model.
When you talk about wanting to intercept function calls, it sounds to me like you're trying to re-invent virtual functions. There's a boat load of ways to get this sort of functionality out of the box, such as inheriting from a base class an overriding its functions.
It sounds to me like you want a class that's more of a wrapper than a derived instance of a base class, so do something like this:
public interface IMyObject
{
object Function1();
object Function2(object arg1);
object Function3(object arg1, object arg2);
}
class MyObject : IMyObject
{
public object Function1() { return null; }
public object Function2(object arg1) { return null; }
public object Function3(object arg1, object arg2) { return null; }
}
class MyObjectInterceptor : IMyObject
{
readonly IMyObject MyObject;
public MyObjectInterceptor()
: this(new MyObject())
{
}
public MyObjectInterceptor(IMyObject myObject)
{
MyObject = myObject;
}
public object Function1()
{
Console.WriteLine("Intercepted Function1");
return MyObject.Function1();
}
public object Function2(object arg1)
{
Console.WriteLine("Intercepted Function2");
return MyObject.Function2(arg1);
}
public object Function3(object arg1, object arg2)
{
Console.WriteLine("Intercepted Function3");
return MyObject.Function3(arg1, arg2);
}
}
2) OR map the input of your functions to a common interface.
This might work if all of your functions are related. For example, if you're writing a game, and all the functions do something to some part of the player or player's inventory. You'd end up with something like this:
class Interceptor
{
private object function1() { return null; }
private object function2(object arg1) { return null; }
private object function3(object arg1, object arg3) { return null; }
Dictionary<string, Func<State, object>> functions;
public Interceptor()
{
functions = new Dictionary<string, Func<State, object>>();
functions.Add("function1", state => function1());
functions.Add("function2", state => function2(state.arg1, state.arg2));
functions.Add("function3", state => function3(state.arg1, state.are2, state.arg3));
}
public object Invoke(string key, object state)
{
Func<object, object> func = functions[key];
return func(state);
}
}
Define the dictionary and add the function reference as the value, using System.Action as the type:
using System.Collections;
using System.Collections.Generic;
public class Actions {
public Dictionary<string, System.Action> myActions = new Dictionary<string, System.Action>();
public Actions() {
myActions ["myKey"] = TheFunction;
}
public void TheFunction() {
// your logic here
}
}
Then invoke it with:
Actions.myActions["myKey"]();
Hey, I hope this helps. What language are you coming from?
internal class ForExample
{
void DoItLikeThis()
{
var provider = new StringMethodProvider();
provider.Register("doSomethingAndGetGuid", args => DoSomeActionWithStringToGetGuid((string)args[0]));
provider.Register("thenUseItForSomething", args => DoSomeActionWithAGuid((Guid)args[0],(bool)args[1]));
Guid guid = provider.Intercept<Guid>("doSomethingAndGetGuid", "I don't matter except if I am null");
bool isEmpty = guid == default(Guid);
provider.Intercept("thenUseItForSomething", guid, isEmpty);
}
private void DoSomeActionWithAGuid(Guid id, bool isEmpty)
{
// code
}
private Guid DoSomeActionWithStringToGetGuid(string arg1)
{
if(arg1 == null)
{
return default(Guid);
}
return Guid.NewGuid();
}
}
public class StringMethodProvider
{
private readonly Dictionary<string, Func<object[], object>> _dictionary = new Dictionary<string, Func<object[], object>>();
public void Register<T>(string command, Func<object[],T> function)
{
_dictionary.Add(command, args => function(args));
}
public void Register(string command, Action<object[]> function)
{
_dictionary.Add(command, args =>
{
function.Invoke(args);
return null;
} );
}
public T Intercept<T>(string command, params object[] args)
{
return (T)_dictionary[command].Invoke(args);
}
public void Intercept(string command, params object[] args)
{
_dictionary[command].Invoke(args);
}
}
The following scenario would allow you to use a dictionary of elements to send in as input parameters and get the same as the output parameters.
First add the following line at the top:
using TFunc = System.Func<System.Collections.Generic.IDictionary<string, object>, System.Collections.Generic.IDictionary<string, object>>;
Then inside your class, define the dictionary as follows:
private Dictionary<String, TFunc> actions = new Dictionary<String, TFunc>(){
{"getmultipledata", (input) =>
{
//DO WORKING HERE
return null;
}
},
{"runproc", (input) =>
{
//DO WORKING HERE
return null;
}
}
};
This would allow you to run these anonymous functions with a syntax similar to this:
var output = actions["runproc"](inputparam);
Why not use params object[] list for method parameters and do some validation inside either your methods (or calling logic), It will allow for a variable number of parameters.