internal class PropertyHelper { private readonly IReadOnlyDictionary _accessors; public PropertyHelper(Type objectType) { var accessors = new Dictionary(); foreach (var propertyInfo in objectType.GetProperties()) { if (propertyInfo.GetIndexParameters().Any()) continue; var propAccessorType = typeof(PropertyAccessor<,>).MakeGenericType(propertyInfo.DeclaringType!, propertyInfo.PropertyType); var accessor = (PropertyAccessor)Activator.CreateInstance(propAccessorType, propertyInfo)!; accessors.Add(propertyInfo.Name, accessor); } _accessors = accessors; } public object? GetPropertyValue(object instance, string propName) => _accessors[propName].Read(instance); public void SetPropertyValue(object instance, string propName, object value) => _accessors[propName].Write(instance, value); private abstract class PropertyAccessor { public abstract object? Read(object instance); public abstract void Write(object instance, object value); } private class PropertyAccessor : PropertyAccessor { private readonly Func _getter; private readonly Action _setter; public PropertyAccessor(PropertyInfo propertyInfo) { _getter = (Func)Delegate.CreateDelegate(typeof(Func), null, propertyInfo.GetGetMethod()!); _setter = (Action)Delegate.CreateDelegate(typeof(Action), null, propertyInfo.GetSetMethod()!); } public override object? Read(object instance) => _getter((T)instance); public override void Write(object instance, object value) => _setter((T)instance, (TProp)value); } } internal class Foo { public string Prop1 { get; set; } public int Prop2 { get; set; } } internal class Program { private static void Main(string[] args) { var propertyHelper = new PropertyHelper(typeof(Foo)); var foo = new Foo(); propertyHelper.SetPropertyValue(foo, "Prop1", "zaza"); propertyHelper.SetPropertyValue(foo, "Prop2", 11); Console.WriteLine("Hello World!"); } }