CreateDelegate(Type, Instance, MethodInfo)

T

tesvit

Hi there,

I am working on a class library that should incpect a given class,
make a delegate to a get Property and use it later on.
Here is the code snippet:

public delegate int MyClassDelegate(MyClass cls);

....

public MyClassDelegate GetGetDelegate(MyClass cls, string memberName)
{
Type objType = cls.GetType();
PropertyInfo propInfo = objType.GetProperty(memberName);
if (propInfo != null)
{
MethodInfo methodInfo = propInfo.GetGetMethod();
if (methodInfo != null)
{
/*1*/ Type dlgType = typeof(MyClassDelegate);
/*2*/ return (MyClassDelegate)Delegate.CreateDelegate(dlgType,
null, methodInfo);
}
else
return null;
}
else
return null;
}

....

Then lather on:


ClassName cls = ...;
string memberName = ...;

ClassDelegate dlg = GetGetDelegate(cls, memberName);

foreach( ClassName c in list)
{
int x = dlg(c);
...
}



Everything works fine.

However, I would like to avoid explicit usage of MyClass and
MyClassDelegate
There is enough information in MethodInfo above to create a delegate.


So, GetGetDelegate() should be:



public Delegate GetGetDelegate(string className, string memberName)
{
Type objType = Type.GetType(className);
...

/*1*/ Type dlgType = CreateDelegateType(methodInfo);
/*2*/ return Delegate.CreateDelegate(dlgType, null, methodInfo);

...
}



The CreateDelegateType() returns the appropriate type of the
MethodInfo.


That works fine too.



But how can I use a delegate now?



Delegate dlg = GetGetDelegate(cls, memberName);

// HOW TO CALL dlg ?


Note that I use this approach mainly because of performance, as
delegate direct call is much faster than dynamic invocation.

Thank you.
 
M

Marc Gravell

3 options depending on what version of C# and .NET (separately) you
are using; see below.

Marc
Note that I use this approach mainly because of performance, as
delegate direct call is much faster than dynamic invocation.

Just another option: http://www.codeproject.com/KB/cs/HyperPropertyDescriptor.aspx

--code--

using System;
using System.Collections.Generic;
using System.Reflection;
using System.Linq.Expressions; // only for .NET 3.5 version

// only for .NET 2.0/3.0 version
//public delegate TResult Func<TArg1, TResult>(TArg1 arg1);


class Foo
{
public Foo() { }
public Foo(int bar) { Bar = bar; }
private int bar;
public int Bar
{
get { return bar; }
set { bar = value; }
}
}

static class Program
{
// only for .NET 3.5 version
public static Func<TArg1, TResult> GetGetDelegate35<TArg1,
TResult>(string memberName)
{
var obj = Expression.Parameter(typeof(TArg1), "obj");
var body = Expression.Property(obj, memberName);
return Expression.Lambda<Func<TArg1, TResult>>(body,
obj).Compile();
}
public static Func<TArg1, TResult> GetGetDelegate20<TArg1,
TResult>(string memberName)
{
Type objType = typeof(TArg1);
PropertyInfo propInfo = objType.GetProperty(memberName);
if (propInfo != null)
{
MethodInfo methodInfo = propInfo.GetGetMethod();
if (methodInfo != null)
{
return (Func<TArg1, TResult>)Delegate.CreateDelegate(
typeof(Func<TArg1, TResult>),
null, methodInfo);
}
else
return null;
}
else
return null;
}

static void Main()
{
// C# 3, .NET 2.0 or above coded
Func<Foo, int> dlg1 = foo => foo.Bar;

// .NET 3.5, dynamic
Func<Foo, int> dlg2 = GetGetDelegate35<Foo, int>("Bar");

// C# 2, .NET 2.0 dynamic
Func<Foo, int> dlg3 = GetGetDelegate20<Foo, int>("Bar");

List<Foo> list = new List<Foo>();
list.Add(new Foo(1));
list.Add(new Foo(2));
list.Add(new Foo(3));

foreach (Foo foo in list)
{
Console.WriteLine(dlg1(foo));
Console.WriteLine(dlg2(foo));
Console.WriteLine(dlg3(foo));
}
}
}

--end code--
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top