Cast delegate to Func in C# - c#

I have code:
public delegate int SomeDelegate(int p);
public static int Inc(int p) {
return p + 1;
}
I can cast Inc to SomeDelegate or Func<int, int>:
SomeDelegate a = Inc;
Func<int, int> b = Inc;
but I can't cast Inc to SomeDelegate and after that cast to Func<int, int> with usual way like this:
Func<int, int> c = (Func<int, int>)a; // Сompilation error
How I can do it?

There's a much simpler way to do it, which all the other answers have missed:
Func<int, int> c = a.Invoke;
See this blog post for more info.

SomeDelegate a = Inc;
Func<int, int> b = Inc;
is short for
SomeDelegate a = new SomeDelegate(Inc); // no cast here
Func<int, int> b = new Func<int, int>(Inc);
You can't cast an instance of SomeDelegate to a Func<int, int> for the same reason you can't cast a string to a Dictionary<int, int> -- they're different types.
This works:
Func<int, int> c = x => a(x);
which is syntactic sugar for
class MyLambda
{
SomeDelegate a;
public MyLambda(SomeDelegate a) { this.a = a; }
public int Invoke(int x) { return this.a(x); }
}
Func<int, int> c = new Func<int, int>(new MyLambda(a).Invoke);

Try this:
Func<int, int> c = (Func<int, int>)Delegate.CreateDelegate(typeof(Func<int, int>),
b.Target,
b.Method);

The problem is that:
SomeDelegate a = Inc;
Isn't actually a cast. It's the short-form of:
SomeDelegate a = new SomeDelegate(Inc);
Therefore there's no cast. A simple solution to your problem can be this (in C# 3.0)
Func<int,int> f = i=>a(i);

This works (in C# 4.0 at least - not tried in earlier versions):
SomeDelegate a = Inc;
Func<int, int> c = new Func<int, int>(a);
If you look at the IL, this compiles into exactly the same code as Winston's answer. Here's the IL for the second line of what I just wrote:
ldloc.0
ldftn instance int32 ConsoleApplication1.Program/SomeDelegate::Invoke(int32)
newobj instance void class [mscorlib]System.Func`2<int32,int32>::.ctor(object, native int)
And that's also precisely what you see if you assign a.Invoke into c.
Incidentally, although Diego's solution is more efficient, in that the resulting delegate refers directly to the underlying method rather than going through the other delegate, it doesn't handle multicast delegates correctly. Winston's solution does, because it just defers completely to the other delegate. If you want a direct solution that also handles delegates with multiple targets, you need something a little more complex:
public static TResult DuplicateDelegateAs<TResult>(MulticastDelegate source)
{
Delegate result = null;
foreach (Delegate sourceItem in source.GetInvocationList())
{
var copy = Delegate.CreateDelegate(
typeof(TResult), sourceItem.Target, sourceItem.Method);
result = Delegate.Combine(result, copy);
}
return (TResult) (object) result;
}
This does the right thing for delegates with a single target by the way—it will end up producing just a single delegate of the target type that refers directly to whatever method (and where applicable, object) the input delegate referred to.

You can hack a cast by using a trick where you use the c# equivalent of a c++ union. The tricky part is the struct with two members that have a [FieldOffset(0)]:
[TestFixture]
public class Demo
{
public void print(int i)
{
Console.WriteLine("Int: "+i);
}
private delegate void mydelegate(int i);
[StructLayout(LayoutKind.Explicit)]
struct funky
{
[FieldOffset(0)]
public mydelegate a;
[FieldOffset(0)]
public System.Action<int> b;
}
[Test]
public void delegatetest()
{
System.Action<int> f = print;
funky myfunky;
myfunky.a = null;
myfunky.b = f;
mydelegate a = myfunky.a;
a(5);
}
}

It is the same kind of problem as this:
public delegate int SomeDelegate1(int p);
public delegate int SomeDelegate2(int p);
...
SomeDelegate1 a = new SomeDelegate1(Inc);
SomeDelegate2 b = (SomeDelegate2)a; // CS0030
which is the same kind of problem as:
public class A { int prop { get; set; } }
public class B { int prop { get; set; } }
...
A obja = new A();
B objb = (B)obja; // CS0029
Objects cannot be casted from one type to an unrelated other type, even though the types are otherwise completely compatible. For lack of a better term: an object has type identity that it carries along at runtime. That identity cannot be changed after the object is created. The visible manifestation of this identity is Object.GetType().

I like examples. Here is my example code:
class Program
{
class A
{
public A(D d) { d.Invoke("I'm A!"); }
public delegate string D(string s);
}
class B
{
public delegate string D(string s);
}
static void Main(string[] args)
{
//1. Func to delegates
string F(dynamic s) { Console.WriteLine(s); return s; }
Func<string, string> f = F;
//new A(f);//Error CS1503 Argument 1: cannot convert from 'System.Func<string, string>' to 'ConsoleApp3.Program.A.D'
new A(new A.D(f));//I'm A!
new A(x=>f(x));//I'm A!
Func<string, string> f2 = s => { Console.WriteLine(s); return s; };
//new A(f2);//Same as A(f)
new A(new A.D(f2));//I'm A!
new A(x => f2(x));//I'm A!
//You can even convert between delegate types
new A(new A.D(new B.D(f)));//I'm A!
//2. delegate to F
A.D d = s => { Console.WriteLine(s); return s; };
Func<string, string> f3 = d.Invoke;
f3("I'm f3!");//I'm f3!
Func<string, string> f4 = new Func<string, string>(d);
f4("I'm f4!");//I'm f4!
Console.ReadLine();
}
}
The output is:

Related

How to create a list of anonymous functions/delegates C#

I have a list object like so
private List<Func<int, double, char, string, string>> FuncList;
And have been attempting to add items to this list using delegates and anonymous functions. The problem is, when I attempt to make a function that has this type, I must return a function from that function. I'm managed to do this recursively, but this throws it into an infinite loop. Is it possible to add functions to this list, and if so how?
I'm attempting to add functions that are passed into a delegate like so
public delegate Func<int, double, char, string, string> funcDelegate(someFunc);
And then do something like this
FuncList.add(funcDelegate);
How would you write someFunc so that this code would work.
My failed attempt at writing a function that returns the correct type is like so, this does not work as it's recursive with no stopping case.
public Func<int, double, char, string, string> SomeFunc(int i, double d, char c, string s1, string s2)
{
Console.WriteLine($"{i}\n{d}\n{c}\n{s1}\n{s2}");
return this.SomeFunc(i,d,c,s1,s2);
}
First, your method doesn't have the right signature. The last generic parameter in Func<> is the return type. Action<> is a generic delegate type that returns void.
Second, the whole point of using Func<> is that you DON'T need to create new types of delegates - Func<> is already a delegate.
Here's an example:
// A list of delegates that accept an integer and return a string
private static List<Func<int, string>> delegateList = new List<Func<int, string>>();
public static string Foo(int x)
{
return $"Foo {x}";
}
public static void Test()
{
delegateList.Add(Foo); // Add a delegate to a named method
delegateList.Add(delegate(int x) { return $"Bar {x * 2}"; } ); // Add a delegate to an anonymous method
delegateList.Add(x => $"Baz {x * 3}"); // Add a delegate to a lambda
foreach (var del in delegateList)
{
Console.WriteLine(del(23));
}
}
In your example, you are declaring a delegate to a function that returns another delegate, but that doesn't seem to be what you're trying to accomplish.
Here's my two cent's worth - it handles arbitrary delegates with up to 4 input parameters, but can be extended ...
public class so40645583
{
private IList<Delegate> FuncList = new List<Delegate>();
public void Add<InputType, OutputType>(Func<InputType, OutputType> func)
{
FuncList.Add(func);
}
public void Add<InT1, InT2, OutputType>(Func<InT1, InT2, OutputType> func)
{
FuncList.Add(func);
}
public void Add<InT1, InT2, InT3, OutputType>(Func<InT1, InT2, InT3, OutputType> func)
{
FuncList.Add(func);
}
public void Add<InT1, InT2, InT3, InT4, OutputType>(Func<InT1, InT2, InT3, InT4, OutputType> func)
{
FuncList.Add(func);
}
// This won't work as it is trying to return a delegate type
// public static Func<int, double, char, string, string> SomeFunc(int i, double d, char c, string s1)
public static string SomeFunc(int i, double d, char c, string s1)
{
return String.Format("{0} {1} {2} {3}", i, d, c, s1);
}
public static string SomeFunc2(int i)
{
return i.ToString();
}
public void Test()
{
Add<int, double, char, string, string>(SomeFunc);
Add<int, string>(SomeFunc2);
// Try invoking via list
Delegate d = FuncList[0];
string s = (string)d.DynamicInvoke(2, 2.0, 'c', "Hi");
Console.WriteLine(s);
// Invoke directly
s = SomeFunc(2, 2.0, 'c', "Hi");
Console.WriteLine(s);
// Now the second one
d = FuncList[1];
s = (string)d.DynamicInvoke(5);
Console.WriteLine(s);
}
}
To run the test:
var so = new so40645583();
so.Test();

cannot infer type parameters using Func [duplicate]

This question already has answers here:
Why can't C# infer type from this seemingly simple, obvious case
(5 answers)
Closed 7 years ago.
A colleague wrote this extension method that I wanted to produce an example for:
namespace ExtensionMethods {
public static class MyExtensions {
public static Res MyAggregate<T, Res>(this IEnumerable<T> source, Func<Res, int, T, Res> f) {
var i = 0;
Res result = default(Res);
foreach (T x in source) {
result = f(result, i, x);
i++;
}
return result;
}
}
}
It creates a generic Aggregate method that also includes an index.
My example (that follows) takes a list of strings and joins the 1st letter from the first word, the 2nd from the second, etc..
namespace ExtensionMethods {
public class Program {
public static string OffsetChars(string x, int i, string y) {
return x + y[i];
}
static void Main(string[] args) {
List<string> test = new List<string>() { "hello", "there", "you" };
// get h from (h)ello, h from t(h)ere and u from yo(u) (hhu)
string result = test.MyAggregate<string, string>(OffsetChars);
Console.WriteLine(result);
Console.ReadKey();
}
}
}
My question is about this line (the important one):
string result = test.MyAggregate<string, string>(OffsetChars);
Without <string, string> there is an error that the types of arguments cannot be inferred from usage. My question(s):
Why cannot they be inferred? Is there something missing from my code that would enable them to be inferred?
I tested with an explicit delegate (follows) but the same error occurs:
namespace ExtensionMethods {
delegate string OffsetMethod(string x, int i, string y);
public class Program {
public static string OffsetChars(string x, int i, string y) {
return x + y[i];
}
static void Main(string[] args) {
List<string> test = new List<string>() { "hello", "there", "you" };
// get h from (h)ello, h from t(h)ere and u from yo(u) (hhu)
OffsetMethod myMethod = OffsetChars;
string result = test.MyAggregate(myMethod);
Console.WriteLine(result);
Console.ReadKey();
}
}
}
To summarize, I want to ensure that I haven't missed anything with my code and, assuming that I haven't, to understand why the parameter types cannot be inferred.
Your method is just a delegate and therefore does not have any generic type arguments that could be infered.
When you define OffsetChars as a generic Func, they can be infered just fine:
public static Func<string, int, string, string> OffsetChars = (x, i, y) =>
{
return x + y[i];
};
WERTZUI is right, because the delegate does not have any generic arguments, compiler cannot infer it, so you have se error.

LINQ: is there a way to supply a predicate with more than one parameter to where clause

wondering if there is a way to do the following:
I basically want to supply a predicate to a where clause with more than one paremeters like the following:
public bool Predicate (string a, object obj)
{
// blah blah
}
public void Test()
{
var obj = "Object";
var items = new string[]{"a", "b", "c"};
var result = items.Where(Predicate); // here I want to somehow supply obj to Predicate as the second argument
}
var result = items.Where(i => Predicate(i, obj));
The operation you want is called "partial evaluation"; it is logically related to "currying" a two-parameter function into two one-parameter functions.
static class Extensions
{
static Func<A, R> PartiallyEvaluateRight<A, B, R>(this Func<A, B, R> f, B b)
{
return a => f(a, b);
}
}
...
Func<int, int, bool> isGreater = (x, y) => x > y;
Func<int, bool> isGreaterThanTwo = isGreater.PartiallyEvaluateRight(2);
And now you can use isGreaterThanTwo in a where clause.
If you wanted to supply the first argument then you could easily write PartiallyEvaluateLeft.
Make sense?
The currying operation (which partially applies to the left) is usually written:
static class Extensions
{
static Func<A, Func<B, R>> Curry<A, B, R>(this Func<A, B, R> f)
{
return a => b => f(a, b);
}
}
And now you can make a factory:
Func<int, int, bool> greaterThan = (x, y) => x > y;
Func<int, Func<int, bool>> factory = greaterThan.Curry();
Func<int, bool> withTwo = factory(2); // makes y => 2 > y
Is that all clear?
Do you expect something like this
public bool Predicate (string a, object obj)
{
// blah blah
}
public void Test()
{
var obj = "Object";
var items = new string[]{"a", "b", "c"};
var result = items.Where(x => Predicate(x, obj)); // here I want to somehow supply obj to Predicate as the second argument
}

Func<T> scope inside class

Why can't I do this?
public int FillModel(int id)
{
// do something...
return 0;
}
public Func<int, int> actiontest = FilleModel;
The code doesn't compile and tells me there is no reference?
As said L.B in his comment you should change:
public Func<int, int> actiontest = FilleModel; //FilleModel doesn't exist
with:
Func<int, int> actiontest = FillModel;
Else if you want to make it public:
public Func<int, int> actiontest;
public myClass(){
actiontest = FillModel;
}
Or:
public Func<int, int> actiontest = FillModel;
private static int FillModel(int id) //private else the delegate doesn't make sense
{
// do something...
return 0;
}
One Important thing, apart from changing:
public Func<int, int> actiontest = FilleModel;
to
Func<int, int> actiontest = FillModel;
You cannot have a direct declaration at the Class level. You can only have such declaration inside some behavior Method or Property setter/getter.

Is there a delegate available for properties in C#?

Given the following class:
class TestClass {
public void SetValue(int value) { Value = value; }
public int Value { get; set; }
}
I can do
TestClass tc = new TestClass();
Action<int> setAction = tc.SetValue;
setAction.Invoke(12);
which is all good. Is it possible to do the same thing using the property instead of the method? Preferably with something built in to .net.
You could create the delegate using reflection :
Action<int> valueSetter = (Action<int>)Delegate.CreateDelegate(typeof(Action<int>), tc, tc.GetType().GetProperty("Value").GetSetMethod());
or create a delegate to an anonymous method which sets the property;
Action<int> valueSetter = v => tc.Value = v;
Edit: used wrong overload for CreateDelegate(), need to use the one that takes and object as target. Fixed.
There are three ways of doing this; the first is to use GetGetMethod()/GetSetMethod() and create a delegate with Delegate.CreateDelegate. The second is a lambda (not much use for reflection!) [i.e. x=>x.Foo]. The third is via Expression (.NET 3.5).
The lambda is the easiest ;-p
class TestClass
{
public int Value { get; set; }
}
static void Main()
{
Func<TestClass, int> lambdaGet = x => x.Value;
Action<TestClass, int> lambdaSet = (x, val) => x.Value = val;
var prop = typeof(TestClass).GetProperty("Value");
Func<TestClass, int> reflGet = (Func<TestClass, int>) Delegate.CreateDelegate(
typeof(Func<TestClass, int>), prop.GetGetMethod());
Action<TestClass, int> reflSet = (Action<TestClass, int>)Delegate.CreateDelegate(
typeof(Action<TestClass, int>), prop.GetSetMethod());
}
To show usage:
TestClass foo = new TestClass();
foo.Value = 1;
Console.WriteLine("Via property: " + foo.Value);
lambdaSet(foo, 2);
Console.WriteLine("Via lambda: " + lambdaGet(foo));
reflSet(foo, 3);
Console.WriteLine("Via CreateDelegate: " + reflGet(foo));
Note that if you want the delegate pointing to the specific instance, you can use closures for the lambda, or the overload of CreateDelegate that accepts and instance.
Properties are really wrappers around methods in .Net, so using reflection you should be able to get the delegate (set_PROPERTY and get_PROPERTY) and then execute them...
See System.Reflection.PropertyInfo
If has two methods which you can use to get/ set the value - GetGetMethod and GetSetMethod.
So you could write:
var propertyInfo = typeof (TestClass).GetProperty ("Value");
var setMethod = property.GetSetMethod (); // This will return a MethodInfo class.

Categories