Skip to content

Instantly share code, notes, and snippets.

@rootn3rd
Created July 26, 2022 19:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rootn3rd/ec9be59850c4a97ad1daffce39579968 to your computer and use it in GitHub Desktop.
Save rootn3rd/ec9be59850c4a97ad1daffce39579968 to your computer and use it in GitHub Desktop.
Expression based property setters
using BenchmarkDotNet.Attributes;
using System.Linq.Expressions;
BenchmarkDotNet.Running.BenchmarkRunner.Run<Runner>();
public class Runner
{
Person p = new Person() { Name = "Pankaj" };
[Benchmark]
public void SetUsingReflection()
{
p.SetUsingReflection(10);
}
[Benchmark]
public void SetUsingExpression()
{
p.SetUsingExpression(20);
}
[Benchmark]
public void SetUsingCompiledExpression()
{
p.SetUsingCompiledExpression(30);
}
}
public static class PersonExtensions
{
public static bool SetUsingReflection(this Person p, int number)
{
var pinfo = typeof(Person).GetProperty("Age", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
if (pinfo == null) return false;
pinfo.SetValue(p, number);
return true;
}
public static bool SetUsingExpression(this Person p, int number)
{
var expr1 = Expression.Parameter(typeof(Person));
var expr2 = Expression.Parameter(typeof(int));
var propertyGetterExpr = Expression.Property(expr1, "Age");
var lambda = Expression.Lambda<Action<Person, int>>(Expression.Assign(propertyGetterExpr, expr2), expr1, expr2);
var compiled = lambda.Compile();
//Console.WriteLine(lambda.ToString());
compiled(p, number);
return true;
}
static readonly Action<Person, int> SetterFunction;
static PersonExtensions() {
var expr1 = Expression.Parameter(typeof(Person));
var expr2 = Expression.Parameter(typeof(int));
var propertyGetterExpr = Expression.Property(expr1, "Age");
var lambda = Expression.Lambda<Action<Person, int>>(Expression.Assign(propertyGetterExpr, expr2), expr1, expr2);
SetterFunction = lambda.Compile();
}
public static bool SetUsingCompiledExpression(this Person p, int number)
{
SetterFunction(p, number);
return true;
}
}
public class Person
{
private int Age { get; set; }
public string Name { get; set; }
public override string ToString()
{
return $"{Name} is of {Age} years";
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment