"dynamic" for anonymous delegates? - c#

I wonder if there is a possibility to make the "dynamic" type for variables work for anonymous delegates.
I've tried the following:
dynamic v = delegate() {
};
But then I got the following error message:
Cannot convert anonymous method to type 'dynamic' because it is not a delegate type
Unfortunately, also the following code doesn't work:
Delegate v = delegate() {
};
object v2 = delegate() {
};
What can I do if I want to make a Method that accepts any type of Delegate, even inline declared ones?
For example:
class X{
public void Y(dynamic d){
}
static void Main(){
Y(delegate(){});
Y(delegate(string x){});
}
}

This works, but it looks a little odd. You can give it any delegate, it will run it and also return a value.
You also need to specify the anonymous method signature at some point in order for the compiler to make any sense of it, hence the need to specify Action<T> or Func<T> or whatever.
Why can't an anonymous method be assigned to var?
static void Main(string[] args)
{
Action d = () => Console.WriteLine("Hi");
Execute(d); // Prints "Hi"
Action<string> d2 = (s) => Console.WriteLine(s);
Execute(d2, "Lo"); // Prints "Lo"
Func<string, string> d3 = (s) =>
{
Console.WriteLine(s);
return "Done";
};
var result = (string)Execute(d3, "Spaghettio"); // Prints "Spaghettio"
Console.WriteLine(result); // Prints "Done"
Console.Read();
}
static object Execute(Delegate d, params object[] args)
{
return d.DynamicInvoke(args);
}

If you declare a type for each of your delegates, it works.
// Declare it somewhere
delegate void DelegateType(string s);
// The cast is required to make the code compile
Test((DelegateType)((string s) => { MessageBox.Show(s); }));
public static void Test(dynamic dynDelegate)
{
dynDelegate("hello");
}

Action _;
dynamic test = (_ = () => Console.WriteLine("Test"));
test() // Test

Related

Creating a Custom Predicate

I am new to Lambda's and Delegates. I think my question may not be a good question but i am trying to write a simple Custom Predicate that act just like a Built-In Prediciate.
So i am going to share my Code: Please share with me that where i am going to make a mistake:
Built-In Predicate Code Example:
namespace Built_In_Predicate
{
class Program
{
static void Main(string[] args)
{
List<string> _ListOfPlayers = new List<string>()
{
"James Anderson",
"Broad",
"foo"
};
// Method 1. Predicate and Anonymous function.
Predicate<string> _Predicate = delegate (string someString) { return someString.Length == 3; };
string result = _ListOfPlayers.Find(_Predicate);
Console.WriteLine("Result : {0}", result);
}
}
}
Trying to Create a Custom Predicate (Code):
namespace CustomPredicate
{
class Program
{
// Delegate (Takes some string as a Input and return a Boolean.)
public delegate bool CustomPredicate(string someString);
static void Main(string[] args)
{
List<string> _ListOfPlayers = new List<string>()
{
"James Anderson",
"Broad",
"foo"
};
// Instance of CustomPredicate.
CustomPredicate customPredicate = delegate (string someString) { return someString.Length == 3; };
string result = _ListOfPlayers.Find(customPredicate); // its error.
}
}
}
Help will be appreciated.
Delegates cannot be implicitly converted to each other even if they have the same signature.
Find expects a System.Predicate<T> so you have to give it a System.Predicate<T>.
You can write your own Find method if you want to use your own CustomPredicate.
There are also ways to use your customPredicate variable in the call to Find:
_ListOfPlayers.Find(new Predicate<string>(customPredicate));
_ListOfPlayers.Find(customPredicate.Invoke);
You cannot call Find with something else as the type Predicate. But if you want your own delegate, you could call FirstOrDefault (System.Linq) and then use it.
private delegate bool CustomPredicate (string t);
static void Main(string[] args)
{
List<string> _ListOfPlayers = new List<string>()
{
"James Anderson",
"Broad",
"foo"
};
// Method 1. Predicate and Anonymous function.
CustomPredicate _Predicate = delegate (string someString) { return someString.Length == 3; };
string result = _ListOfPlayers.FirstOrDefault(x => _Predicate(x));
Console.WriteLine("Result : {0}", result);
Console.ReadLine();
}

Delegate that returns a delegate

I'm trying to create a delegate that will return a delegate. I then want to invoke this delegate, and also invoke the returned inner delegate. My question is: Why is this causing an error? And how to I change this code to accomplish what I'm trying to do?
The error message is 'Method name expected'.
delegate string del();
delegate Delegate nestedDel();
public static void main()
{
nestedDel myNestedDel = () =>
{
del myInnerDel = () => { return "inside"; };
return myInnerDel;
};
Delegate k = myNestedDel();
k(); // Error!!!
}
In short, you've messed up the types. One of the delegates should return the other one, so its return type should simply be the type of the other delegate. In your code example:
delegate string del();
delegate Delegate nestedDel();
you are in fact returning a delegate, but Delegate or MulticastDelegate are just infrastructure base classes and are not invocable directly. By using these classes you're losing information about list of parameters and return values, so simple call() operator cannot work. As Lee mentioned in comments, you could do it by k.DynamicInvoke() but that's.. overkill. Just use a proper type name instead of Delegate.
Working example:
delegate string InnerDel();
delegate InnerDel OuterDel(); // this one returns an instance of Inner delegate
public static void Main()
{
OuterDel myOuterDelegate = () =>
{
InnerDel myInnerDel = () => { return "inside"; };
return myInnerDel;
};
InnerDel k = myOuterDelegate();
k();
}
Personally, I like Func/Actions more than defining my own delegate classes... at least as long as they have at most few parameters. In terms of func/action it would look like this:
public static void Main()
{
Func<Func<string>> myOuterDelegate = () =>
{
Func<string> myInnerDel = () => { return "inside"; };
return myInnerDel;
};
var k = myOuterDelegate();
k();
}
or even..
public static void Main()
{
Func<Func<string>> myOuterDelegate = () => () => { return "inside"; };
var k = myOuterDelegate();
k();
}
Your error is because instances of the Delegate type cannot be invoked with the function call syntax i.e. as k();.
You can call it using DynamicInvoke:
string s = (string)k.DynamicInvoke();
obviously this is prone to runtime errors so a better approach would be to change the return type of nestedDel e.g.
delegate Func<string> nestedDel();
nestedDel myNestedDel = () =>
{
Func<string> myInnerDel = () => { return "inside"; };
return myInnerDel;
};
stringk = myNestedDel();

How can i access the value of a local variable from within an expression tree

By examining an expression tree i can get the value of a constant, instance field and property but not a local variable defined in a method.
Executing the following will output 1, 2, 3 (from the constant, instance field and property) then an exception as i don't know how to get the instance on which the FieldInfo is declared in order to call GetValue() for the local variable.
using System;
using System.Linq.Expressions;
using System.Reflection;
namespace Example
{
class Program
{
private int _intField = 2;
static void Main()
{
new Program().Run();
Console.ReadLine();
}
private void Run()
{
IntProp = 3;
var intVariable = 4;
Test(() => 1);
Test(() => _intField);
Test(() => IntProp);
Test(() => intVariable);
}
public int IntProp { get; set; }
void Test<T>(Expression<Func<T>> func)
{
var body = func.Body;
if (body.NodeType == ExpressionType.Constant)
{
Console.WriteLine(((ConstantExpression)body).Value);
}
else
{
var memberExpression = body as MemberExpression;
var #object = memberExpression.Member.DeclaringType == GetType()
? this
: null; //Can I do anything here? Instance of the method the variable is defined in?
if (memberExpression.Member.MemberType == MemberTypes.Field)
{
Console.WriteLine(((FieldInfo)memberExpression.Member).GetValue(#object));
}
else if (memberExpression.Member.MemberType == MemberTypes.Property)
{
Console.WriteLine(((PropertyInfo)memberExpression.Member).GetValue(#object));
}
}
}
}
}
The local variable which has been captured by the lambda and included in the expression tree, will at that time really be a field on some compiler-generated class. This works on my version of .NET:
void Test<T>(Expression<Func<T>> func)
{
var body = func.Body;
if (body.NodeType == ExpressionType.Constant)
{
Console.WriteLine(((ConstantExpression)body).Value);
}
else
{
var memberExpression = (MemberExpression)body;
var #object =
((ConstantExpression)(memberExpression.Expression)).Value; //HERE!
if (memberExpression.Member.MemberType == MemberTypes.Field)
{
Console.WriteLine(((FieldInfo)memberExpression.Member).GetValue(#object));
}
else if (memberExpression.Member.MemberType == MemberTypes.Property)
{
Console.WriteLine(((PropertyInfo)memberExpression.Member).GetValue(#object));
}
}
}
Of course, you can also "cheat":
void Test<T>(Expression<Func<T>> func)
{
Console.WriteLine(func.Compile()());
}
No, you cannot.
Reflection does not extend to reading the values of method variable.
It only handles the declaration metadata of variables. And even then, the compiler may have removed the variable you thought you declared. You allready can access to properties, fields.
No, you cannot because those variables are simply not available outside the method their scope.
No you can't with reflection. But there are other methods to do so. As an example, I show you how to export a variable out of the functions' lexical scope.
Say you have a method like this:
private void f(int x)
{
// your code here
}
You also have a piece of code like this:
int x_in_f;
f(3);
x_in_f = /* I want to have the value here */;
To get the value out of f() you must export a getter function. As f() returns void, you just could return the getter. In a general case (when f() has a non-void return type) you can leverage an out parameter. Here are both variants:
private Func<int> f(int x)
{
// your code here
return () => { return x; };
}
or through the out parameter:
private void f(int x, out Func<int> g)
{
// your code here
g = () => { return x; };
}
The code would then be:
int x_in_f;
Func<int> g;
g = f(3);
x_in_f = g(); // this will return the value of x as it was passed to f()
or through the out parameter invoke f() as follows:
f(3, out g);
At that point you can pass g() around to other functions:
private void h(Func<int> getx)
{
// your code here
int x = getx();
// now you have the value of x inside the h() function
}
and the invocation with h():
Func<int> g = f(3);
// ...
h(g);
I hope this helps or at least shows how to use closures to circumvent lexical scoping.
For the designers out there, this is the Object Capability Model. This is a video by Douglas Crockford on how to use it for security purposes in Javascript. It translates to C# and other purposes easily, as I've shown above.

How do I create and call an Action<T> when I only know T at runtime?

How do I create and call a delegate Action<T> when at runtime I'm receiving the delegate as an object and I know type only at runtime?
For example, In Foo, I define my delegate and want to pass it to a method which receives an Action<int> as an object, along with the data to pass to the delegate. It's contrived I know, but it's to demonstrate my problem.
public void Foo()
{
Action<int> handler = i => Console.WriteLine(i + 1);
Process(handler,4)
}
public void Process(object myDelegate, object data)
{
}
and I'd like to call
myDelegate(data)
All the delegate types (Eg. Action<string>) Are actually types that have an Invoke(...) method.
You should look for that invoke method with reflection and call it, It is relatively slow - So watch out.
This should do it :
Action<string> action = s => Console.WriteLine("Hello " + s);
object obj = action;
// Invoking
obj.GetType ().GetMethod ("Invoke").Invoke (obj, new object[] {"World"});
This works too, I don't know what is faster, you should check it out :
Action<string> action = s => Console.WriteLine("Hello " + s);
Delegate obj = action;
obj.DynamicInvoke(new [] { "World" });
So maybe this then:
public void processAction<T>(Action<T> action, T item) {
action(item);
}
Action<int> customAction = (i) => Console.WriteLine(i);
processAction(customAction, 123);
Action<string> customAction2 = (s) => Console.WriteLine(s);
processAction(customAction2, "Frank Borland");
This should work
Action<int> handler = i => Console.WriteLine(i + 1);
Process(handler, 4);
public void Process(object myDelegate, object data)
{
((Delegate)myDelegate).DynamicInvoke(data);
}
You haven't given a whole lot of context here, but can't you rewrite you Process method as:
public void Process<T>(Action<T> myDelegate, T data)
{
myDelegate(data);
}

How to convert delegate to object in C#?

I am using reflection class to invoke some methods which are on the some other dll.
And one of the methods' parameters are type of delegate.
And I want to invoke this methods by using reflection.
So I need to pass function parameters as object array, but I could not find anything about
how to convert delegate to object.
Thanks in advance
A delegate is an object. Just create the expected delegate as you would normally, and pass it in the parameters array. Here is a rather contrived example:
class Mathematician {
public delegate int MathMethod(int a, int b);
public int DoMaths(int a, int b, MathMethod mathMethod) {
return mathMethod(a, b);
}
}
[Test]
public void Test() {
var math = new Mathematician();
Mathematician.MathMethod addition = (a, b) => a + b;
var method = typeof(Mathematician).GetMethod("DoMaths");
var result = method.Invoke(math, new object[] { 1, 2, addition });
Assert.AreEqual(3, result);
}
Instances of delegates are objects, so this code works (C#3 style) :
Predicate<int> p = (i)=> i >= 42;
Object[] arrayOfObject = new object[] { p };
Hope it helps !
Cédric
Here's an example:
class Program
{
public delegate void TestDel();
public static void ToInvoke(TestDel testDel)
{
testDel();
}
public static void Test()
{
Console.WriteLine("hello world");
}
static void Main(string[] args)
{
TestDel testDel = Program.Test;
typeof(Program).InvokeMember(
"ToInvoke",
BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static,
null,
null,
new object[] { testDel });
}
}
I think this blog post:
C# Reflection - Dealing with Remote Objects
answers your question perfectly.
you can see a delegate as variable type "function". the delegate describes the parameters and return value for a matching function.
delegate void Foo(int a); // here a new delegate obj type Foo has been declared
the above example allows 'Foo' to be used as a data type, the only allowed object that can be matched with a variable of type Foo data type is a method with the same signature so:
void MyFunction(int x);
Foo D = MyFunction; // this is OK
void MyOtherFunction(string x);
Foo D = MyOtherFunction; // will yield an error since not same signature.
Once you have assigned a method to a delegate, you can invoke the method via the delegate:
int n = 1;
D( n ); // or D.Invoke( n );

Categories

Resources