Using partially matching functions as delegates? - c#

Lets say I have:
static void Foo(string s, int i){//some implementation}
static void Bar(string s){//some other implementation}
delegate void Del(string s);
obviously, it is possible to go:
Del d = Bar
but is it possible to do something like:
Del d2 = Foo(7); //just takes in string s as the only parameter;
I'm wondering if there is a way to redefine some of the parameters so that the leftover parameters match the signature of the delegate.
Is this possible without having to define an intermediate method like this:
static void IntermediateMethod(string s){ return Foo(s, 7);}
`

I think this is the closest I can get to what I wanted.
Del d2 = delegate(string s){Foo(s,7);};
This basically achieves my goal since the method is anonymous and you don't need an intermediate method.

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.

Why do I have to state parameter type when assigning a delegate function to a delegate variable?

Say I have a delegate like this.
namespace somedelegatesb1 {
class Program {
delegate int Abc(int a);
static void Main(string[] args) {
Abc abc = delegate(int e) {
return 0;
};
}
}
}
Why is it that I have to write the parameter int e, here
Abc abc = delegate(int e) {
return 0;
};
Why can't I write
Abc abc = delegate(e) {
return 0;
};
It won't compile, but isn't it 'obvious' that it would be int e? what else would it be? It's impossible to be anything other than int e, since the delegate requires int e.
And suppose i'm not using a parameter, i.e. the function will take a parameter but say it won't use the variable. then it's completely pointless. Why can't I write
Abc abc = delegate {
return 0;
};
And even if I was using a parameter.. the variable name is not necessarily that relevant for example in javascript you can say arguments[0]. So why not allow Abc abc = delegate {...};
I know C# is strictly typed, but i'm not sugggesting changing the type when writing the type after delegate. And i'm not suggesting c# allow passing in more or less parameters than have been defined. It's just superfluous to write the type. Even the variable name in some cases isn't necessary e.g. if not using it, though one would normally use it so I can see why they might mandate that, but certainly the type here is absolutely unnececessary and pointless. So why does C# seem to require it?

Passing array of Argument into multiple parameter function in C#

Life is short
def foo(b,a,r):
# bla bla bla
pass
mylist = ['b','a','r']
foo(*mylist)
That's how passing a list of arguments into method multiple positional parameters in Python.
But in C# I found out passing an array into a parameter of array using the params keywords, like this one:
void foo(params string[] bar)
{
// bla bla bla
}
string[] mylist = {"b", "a", "r"};
foo(mylist)
Imagine how If I cannot touch the function, is there an easier way
Is there a way to do that?
Here is what I mean:
void foo (string b, string a, string r)
{
// bla bla bla
}
string[] mylist = {"b", "a", "r"};
foo(mylist[0],mylist[1],mylist[2]); // This line makes my life difficult
I search online and can't found an alternative of it. Just want to make sure that I didn't miss the hidden feature that C# provide. Who know there's such shortcut for us?
No, there is no feature in C# that allows you to do this directly. But there are some ways you can use to work around that:
Create a method that converts a method with several parameters into a method with one array parameter:
static Action<T[]> ToArrayMethod<T>(Action<T, T, T> original)
{
return array => original(array[0], array[1], array[2]);
}
And then use it like this:
string[] array = {"b", "a", "r"};
var arrayFoo = ToArrayMethod(foo);
arrayFoo(array);
The downside of this approach is that this method works only on methods with exactly three parameters with a void return type. You would need to write another overload of ToArrayMethod() if you wanted this to work for methods with, say, 4 parameters, or for those that return some value.
Use reflection. When doing that, arguments are passed in using an array:
var foo = typeof(SomeType)
.GetMethod("foo", BindingFlags.Instance | BindingFlags.NonPublic);
object[] array = {"b", "a", "r"};
foo.Invoke(somTypeInstance, array);
There is downsides to using static languages, and this is one of them, if your function signature is defined as:
void foo (string a, string b, string c);
then you are forced to pass in 3 separate strings
foo(mylist[0],mylist[1],mylist[2]);
the only way to have flexible inputs in C# is by using params which you already now, or by using default values (C# 4.0):
void foo (string a, string b = null, string c = null)
meaning that if I don't pass b or c just set them to null, and now you can call your function like this:
foo(mylist[0])
You could use reflection; however, that typically isn’t recommended because it makes you sacrifice compile-time type-safety checking.
Here is a sample approach:
string[] mylist = { "b", "a", "r" };
((Action<string,string,string>)foo).DynamicInvoke(mylist);
There is no shortcut. If you want to get crazy and you're able to modify the function somewhat, you could overload it to have one signature with the params keyword, and have the original overload pass its arguments into the the new one.
So to summarize a lot of replies here, you'll need a sort of a hack for this and the cleanest way in my opinion is something along these lines:
Create an extension function for enumerables:
public static class Extensions
{
public static void SendToMethod<T>(this IEnumerable<T> self, Delegate func )
{
Contract.Requires(func.Method.GetParameters().Length == self.Count());
func.DynamicInvoke(self.Cast<object>().ToArray());
}
}
Then you can send the array to any function having an argument count equal to the length of the enumerable:
public void foo(string a, int b, bool c, string d) {}
public void foo2(string a, string b, string c) {}
...
var test1 = new object[] {"ASDF", 10, false, "QWER"};
var test2 = new[] {"A", "B", "C"};
test2.SendToMethod((Action<string, string, string>)foo);
test1.SendToMethod((Action<string, int, bool, string>)foo2);

C#; making a new delegate without declaring the method separately?

I'm able to compile code that includes this:
OperationDelegate myOpDelegate;
static OperatorDefinition[] definitions ={
new OperatorDefinition("+",2,3,true, new OperationDelegate(OperationAdd)),
};
delegate double OperationDelegate(double[] args);
static double OperationAdd(double[] args)
{
return args[0] + args[1];
}
but I think my code would look cleaner if I could do something more like this:
OperationDelegate myOpDelegate;
static OperatorDefinition[] definitions ={new OperatorDefinition("+",2,3,true, new OperationDelegate({return args[0]+args[1]}))};
delegate double OperationDelegate(double[] args);
because I want to define everything about each OperatorDefinition in a single place, rather than defining the functions separately. Is there some way to do this in C#?
(any other criticism about my code would be welcome, too)
Look into anonymous methods... for example this: C# - Anonymous delegate
You can use Lambda expressions as from .Net 3.5:
static OperatorDefinition[] definitions ={
new OperatorDefinition("+",2,3,true,
args => args[0] + args[1])
};
In your OperatorDefinition constructor, last parameter should be of type Func<double[],double>
See:
http://msdn.microsoft.com/en-us/library/bb397687.aspx

C# ambiguity in Func + extension methods + lambdas

I've been trying to make my way through this article:
http://blogs.msdn.com/wesdyer/archive/2008/01/11/the-marvels-of-monads.aspx
... And something on page 1 made me uncomfortable. In particular, I was trying to wrap my head around the Compose<>() function, and I wrote an example for myself. Consider the following two Func's:
Func<double, double> addTenth = x => x + 0.10;
Func<double, string> toPercentString = x => (x * 100.0).ToString() + "%";
No problem! It's easy to understand what these two do.
Now, following the example from the article, you can write a generic extension method to compose these functions, like so:
public static class ExtensionMethods
{
public static Func<TInput, TLastOutput> Compose<TInput, TFirstOutput, TLastOutput>(
this Func<TFirstOutput, TLastOutput> toPercentString,
Func<TInput, TFirstOutput> addTenth)
{
return input => toPercentString(addTenth(input));
}
}
Fine. So now you can say:
string x = toPercentString.Compose<double, double, string>(addTenth)(0.4);
And you get the string "50%"
So far, so good.
But there's something ambiguous here. Let's say you write another extension method, so now you have two functions:
public static class ExtensionMethods
{
public static Func<TInput, TLastOutput> Compose<TInput, TFirstOutput, TLastOutput>(
this Func<TFirstOutput, TLastOutput> toPercentString,
Func<TInput, TFirstOutput> addTenth)
{
return input => toPercentString(addTenth(input));
}
public static Func<double, string> Compose<TInput, TFirstOutput, TLastOutput>(this
Func<double, string> toPercentString,
Func<double, double> addTenth)
{
return input => toPercentString(addTenth(input + 99999));
}
}
Herein is the ambiguity. Don't these two function have overlapping signatures? Yes. Does this even compile? Yes. Which one get's called? The second one (which clearly gives you the "wrong" result) gets called. If you comment out either function, it still compiles, but you get different results.
It seems like nitpicking, but there's something that deeply offends my sensibilities here, and I can't put my finger on it. Does it have to do with extension methods? Does it have to do with lambdas? Or does it have to do with how Func<> allows you to parameterize the return type? I'm not sure.
I'm guessing that this is all addressed somewhere in the spec, but I don't even know what to Google to find this.
Help!
There's nothing ambiguous here. The second one will get called whenever it is an exact match. Whenever the match is not exact, you get the first function, because by default it is going to be an exact match for everything else.
If you create a Func<double, string>, and another that is Func<double, double>, call .Compose while explicitly specifying <double, double, string>, the compiler has enough information to determine that the second version is going to be an exact match and therefore it is the one used.
But consider this foolish example:
Func<string, string> doubleString = s => s + s;
Func<DateTime, string> dateToString = date => date.ToString();
Func<DateTime, string> composedFunction = doubleString.Compose(dateToString);
Console.WriteLine(composedFunction(DateTime.Now));
Which version gets called? What's the result? The first version, and the output is the date as a string concatenated to itself.
On the other hand, if you had a more realistic example using Func<double, string> and Func<double, double> and weren't as explicit with the call to Compose, which version gets called?
Func<double, string> toPercentString = d => d.ToString("0.0%");
Func<double, double> addTenth = d => d + 0.1;
Console.WriteLine(toPercentString.Compose(addTenth)(0.8));
The first one, because the compiler determines it to be the exact match versus the second. Since I'm not Eric Lippert or Jon Skeet, I'll not even attempt to explain the binding on that one.
static void DoSomething(float f, double d) { }
static void DoSomething(double d, float f) { }
...
DoSomething(1, 1);
This is ambiguous (and doesn't compile because of it).
I don't see what this has to do with delegates, generics, or extension methods; your fundamental problem seems to be with overloading (and specifically, method overload resolution when there are multiple candidates). Consider:
public static class Test {
public static void Method(string s) {
Console.WriteLine("String version: " + s);
}
public static void Method(object o) {
Console.WriteLine("Object version: " + o.ToString());
}
public static void Main(string[] args) { Method("my string"); }
}
In Main, which method gets called? Is there ambiguity? Overload resolution kicks during compilation and one method is determined to be a better fit (the method taking a string). Just as in your case, commenting out the first overload will result in code which compiles but calls the other overload. The same thing happens if the second method is defined as:
public static void Method<T>(T t) {
Console.WriteLine("Generic version: " + t.ToString());
}
Although this is a candidate for overload resolution, the overload taking a string is an exact match and is preferred.

Categories