How do I create a delegate for a .NET property?


I am trying to create a delegate (as a test) for:

Public Overridable ReadOnly Property PropertyName() As String

My intuitive attempt was declaring the delegate like this:

Public Delegate Function Test() As String

And instantiating like this:

Dim t As Test = AddressOf e.PropertyName

But this throws the error:

Method 'Public Overridable ReadOnly Property PropertyName() As String' does not have a signature compatible with delegate 'Delegate Function Test() As String'.

So because I was dealing with a property I tried this:

Public Delegate Property Test() As String

But this throws a compiler error.

So the question is, how do I make a delegate for a property?

See this link:

7/21/2013 6:59:30 AM

Accepted Answer

Re the problem using AddressOf - if you know the prop-name at compile time, you can (in C#, at least) use an anon-method / lambda:

Test t = delegate { return e.PropertyName; }; // C# 2.0
Test t = () => e.PropertyName; // C# 3.0

I'm not a VB expert, but reflector claims this is the same as:

Dim t As Test = Function 
    Return e.PropertyName
End Function

Does that work?

Original answer:

You create delegates for properties with Delegate.CreateDelegate; this can be open for any instance of the type, of fixed for a single instance - and can be for getter or setter; I'll give an example in C#...

using System;
using System.Reflection;
class Foo
    public string Bar { get; set; }
class Program
    static void Main()
        PropertyInfo prop = typeof(Foo).GetProperty("Bar");
        Foo foo = new Foo();

        // create an open "getter" delegate
        Func<Foo, string> getForAnyFoo = (Func<Foo, string>)
            Delegate.CreateDelegate(typeof(Func<Foo, string>), null,

        Func<string> getForFixedFoo = (Func<string>)
            Delegate.CreateDelegate(typeof(Func<string>), foo,

        Action<Foo,string> setForAnyFoo = (Action<Foo,string>)
            Delegate.CreateDelegate(typeof(Action<Foo, string>), null,

        Action<string> setForFixedFoo = (Action<string>)
            Delegate.CreateDelegate(typeof(Action<string>), foo,

        setForAnyFoo(foo, "abc");
4/8/2009 5:42:26 AM

I just create an helper with pretty good performance : It don't use IL / Emit approach and it is very fast !

Edit by oscilatingcretin 2015/10/23

The source contains some casing issues and peculiar ="" that have to be removed. Before link rot sets in, I thought I'd post a cleaned-up version of the source for easy copy pasta, as well as an example of how to use it.

Revised source

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace Tools.Reflection
    public interface IPropertyAccessor
        PropertyInfo PropertyInfo { get; }
        object GetValue(object source);
        void SetValue(object source, object value);

    public static class PropertyInfoHelper
        private static ConcurrentDictionary<PropertyInfo, IPropertyAccessor> _cache =
            new ConcurrentDictionary<PropertyInfo, IPropertyAccessor>();

        public static IPropertyAccessor GetAccessor(PropertyInfo propertyInfo)
            IPropertyAccessor result = null;
            if (!_cache.TryGetValue(propertyInfo, out result))
                result = CreateAccessor(propertyInfo);
                _cache.TryAdd(propertyInfo, result); ;
            return result;

        public static IPropertyAccessor CreateAccessor(PropertyInfo PropertyInfo)
            var GenType = typeof(PropertyWrapper<,>)
                .MakeGenericType(PropertyInfo.DeclaringType, PropertyInfo.PropertyType);
            return (IPropertyAccessor)Activator.CreateInstance(GenType, PropertyInfo);

    internal class PropertyWrapper<TObject, TValue> : IPropertyAccessor where TObject : class
        private Func<TObject, TValue> Getter;
        private Action<TObject, TValue> Setter;

        public PropertyWrapper(PropertyInfo PropertyInfo)
            this.PropertyInfo = PropertyInfo;

            MethodInfo GetterInfo = PropertyInfo.GetGetMethod(true);
            MethodInfo SetterInfo = PropertyInfo.GetSetMethod(true);

            Getter = (Func<TObject, TValue>)Delegate.CreateDelegate
                    (typeof(Func<TObject, TValue>), GetterInfo);
            Setter = (Action<TObject, TValue>)Delegate.CreateDelegate
                    (typeof(Action<TObject, TValue>), SetterInfo);

        object IPropertyAccessor.GetValue(object source)
            return Getter(source as TObject);

        void IPropertyAccessor.SetValue(object source, object value)
            Setter(source as TObject, (TValue)value);

        public PropertyInfo PropertyInfo { get; private set; }

Use it like this:

public class MyClass
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int Age { get; set; }

MyClass e = new MyClass();
IPropertyAccessor[] Accessors = e.GetType().GetProperties()
    .Select(pi => PropertyInfoHelper.CreateAccessor(pi)).ToArray();

foreach (var Accessor in Accessors)
    Type pt = Accessor.PropertyInfo.PropertyType;
    if (pt == typeof(string))
        Accessor.SetValue(e, Guid.NewGuid().ToString("n").Substring(0, 9));
    else if (pt == typeof(int))
        Accessor.SetValue(e, new Random().Next(0, int.MaxValue));

        Accessor.PropertyInfo.Name, Accessor.GetValue(e)));

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow