Last active
December 25, 2022 14:55
-
-
Save AptiviCEO/23ce0a19ffe5cd7e290e083b89808eff to your computer and use it in GitHub Desktop.
Fields and properties get and set functions using expression
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Linq; | |
using System.Collections.Generic; | |
using System.Diagnostics; | |
using System.Reflection; | |
using System.Linq.Expressions; | |
namespace Aptivi; | |
class ExpressionGetSet | |
{ | |
// --------------------------- Test classes --------------------------- | |
public static class Person | |
{ | |
public static String Title = "Product Manager"; | |
public static String Name { get; set; } = "John"; | |
} | |
public class App | |
{ | |
public String Desc = "Chat on IRC from anywhere, and never miss a message"; | |
public String Name { get; set; } = "IRCCloud"; | |
} | |
// --------------------------- Get and set property using expression in static mode --------------------------- | |
private static object ExpressionGetPropertyStatic(Type type, string property) | |
{ | |
if (type is null) | |
throw new ArgumentNullException(nameof(type)); | |
if (property is null) | |
throw new ArgumentNullException(nameof(property)); | |
var propertyInfo = type.GetProperty(property); | |
var instanceParam = Expression.Parameter(type); | |
var callExpr = Expression.Call(propertyInfo.GetGetMethod()); | |
var convExpr = Expression.Convert(callExpr, typeof(Object)); | |
var expression = Expression.Lambda<Func<Object>>(convExpr).Compile(); | |
return expression(); | |
} | |
private static void ExpressionSetPropertyStatic(Type type, string property, object value) | |
{ | |
if (type is null) | |
throw new ArgumentNullException(nameof(type)); | |
if (property is null) | |
throw new ArgumentNullException(nameof(property)); | |
if (value is null) | |
throw new ArgumentNullException(nameof(value)); | |
var propertyInfo = type.GetProperty(property); | |
var argumentParam = Expression.Parameter(typeof(Object)); | |
var convExpr = Expression.Convert(argumentParam, propertyInfo.PropertyType); | |
var callExpr = Expression.Call(propertyInfo.GetSetMethod(), convExpr); | |
var expression = Expression.Lambda<Action<object>>(callExpr, argumentParam).Compile(); | |
expression(value); | |
} | |
// --------------------------- Get and set property using expression in instance mode --------------------------- | |
private static object ExpressionGetPropertyInstance<T>(T instance, string property) | |
{ | |
if (instance is null) | |
throw new ArgumentNullException(nameof(instance)); | |
if (property is null) | |
throw new ArgumentNullException(nameof(property)); | |
var type = instance.GetType(); | |
var propertyInfo = type.GetProperty(property); | |
var instanceParam = Expression.Parameter(type); | |
var callExpr = Expression.Call(instanceParam, propertyInfo.GetGetMethod()); | |
var convExpr = Expression.Convert(callExpr, typeof(Object)); | |
var expression = Expression.Lambda<Func<T, Object>>(convExpr, instanceParam).Compile(); | |
return expression(instance); | |
} | |
private static void ExpressionSetPropertyInstance<T>(T instance, string property, object value) | |
{ | |
if (instance is null) | |
throw new ArgumentNullException(nameof(instance)); | |
if (property is null) | |
throw new ArgumentNullException(nameof(property)); | |
if (value is null) | |
throw new ArgumentNullException(nameof(value)); | |
var type = instance.GetType(); | |
var propertyInfo = type.GetProperty(property); | |
var instanceParam = Expression.Parameter(type); | |
var argumentParam = Expression.Parameter(typeof(Object)); | |
var convExpr = Expression.Convert(argumentParam, propertyInfo.PropertyType); | |
var callExpr = Expression.Call(instanceParam, propertyInfo.GetSetMethod(), convExpr); | |
var expression = Expression.Lambda<Action<T, object>>(callExpr, instanceParam, argumentParam).Compile(); | |
expression(instance, value); | |
} | |
// --------------------------- Get and set field using expression in static mode --------------------------- | |
private static object ExpressionGetFieldStatic(Type type, string field) | |
{ | |
if (type is null) | |
throw new ArgumentNullException(nameof(type)); | |
if (field is null) | |
throw new ArgumentNullException(nameof(field)); | |
var fieldInfo = type.GetField(field); | |
var assignExpr = Expression.Field(null, fieldInfo.DeclaringType, fieldInfo.Name); | |
var convExpr = Expression.Convert(assignExpr, typeof(object)); | |
var expression = Expression.Lambda<Func<object>>(convExpr).Compile(); | |
return expression(); | |
} | |
private static void ExpressionSetFieldStatic(Type type, string field, object value) | |
{ | |
if (type is null) | |
throw new ArgumentNullException(nameof(type)); | |
if (field is null) | |
throw new ArgumentNullException(nameof(field)); | |
if (value is null) | |
throw new ArgumentNullException(nameof(value)); | |
var fieldInfo = type.GetField(field); | |
var argumentParam = Expression.Parameter(typeof(object)); | |
var assignExpr = Expression.Field(null, fieldInfo.DeclaringType, fieldInfo.Name); | |
var convertExpr = Expression.Convert(argumentParam, assignExpr.Type); | |
var setExpr = Expression.Assign(assignExpr, convertExpr); | |
var expression = Expression.Lambda<Action<object>>(setExpr, argumentParam).Compile(); | |
expression(value); | |
} | |
// --------------------------- Get and set field using expression in instance mode --------------------------- | |
private static object ExpressionGetFieldInstance<T>(T instance, string field) | |
{ | |
if (instance is null) | |
throw new ArgumentNullException(nameof(instance)); | |
if (field is null) | |
throw new ArgumentNullException(nameof(field)); | |
var type = instance.GetType(); | |
var fieldInfo = type.GetField(field); | |
var instanceParam = Expression.Parameter(type); | |
var assignExpr = Expression.Field(instanceParam, fieldInfo); | |
var convExpr = Expression.Convert(assignExpr, typeof(object)); | |
var expression = Expression.Lambda<Func<T, object>>(convExpr, instanceParam).Compile(); | |
return expression(instance); | |
} | |
private static void ExpressionSetFieldInstance<T>(T instance, string field, object value) | |
{ | |
if (instance is null) | |
throw new ArgumentNullException(nameof(instance)); | |
if (field is null) | |
throw new ArgumentNullException(nameof(field)); | |
if (value is null) | |
throw new ArgumentNullException(nameof(value)); | |
var type = instance.GetType(); | |
var fieldInfo = type.GetField(field); | |
var instanceParam = Expression.Parameter(type); | |
var argumentParam = Expression.Parameter(typeof(object)); | |
var convExpr = Expression.Convert(argumentParam, fieldInfo.FieldType); | |
var assignExpr = Expression.Field(instanceParam, fieldInfo); | |
var setExpr = Expression.Assign(assignExpr, convExpr); | |
var expression = Expression.Lambda<Action<T, object>>(setExpr, instanceParam, argumentParam).Compile(); | |
expression(instance, value); | |
} | |
// --------------------------- CUT HERE --------------------------- | |
public static void Main() | |
{ | |
Console.WriteLine("---------- Static set/get using expression on properties ----------"); | |
Console.WriteLine($"Person name before set: {Person.Name}"); | |
Console.WriteLine($"Person name using exp: {ExpressionGetPropertyStatic(typeof(Person), "Name")}"); | |
ExpressionSetPropertyStatic(typeof(Person), "Name", "Trevor"); | |
Console.WriteLine($"Person name after set: {Person.Name}"); | |
Console.WriteLine($"Person name using exp: {ExpressionGetPropertyStatic(typeof(Person), "Name")}"); | |
Console.WriteLine(); | |
Console.WriteLine("---------- Instance set/get using expression on properties ----------"); | |
var aid = new App(); | |
Console.WriteLine($"App name before set: {aid.Name}"); | |
Console.WriteLine($"App name using exp: {ExpressionGetPropertyInstance(aid, "Name")}"); | |
ExpressionSetPropertyInstance(aid, "Name", "Mastodon"); | |
Console.WriteLine($"App name after set: {aid.Name}"); | |
Console.WriteLine($"App name using exp: {ExpressionGetPropertyInstance(aid, "Name")}"); | |
Console.WriteLine(); | |
Console.WriteLine("---------- Static set/get using expression on fields ----------"); | |
Console.WriteLine($"Person name before set: {Person.Title}"); | |
Console.WriteLine($"Person name using exp: {ExpressionGetFieldStatic(typeof(Person), "Title")}"); | |
ExpressionSetFieldStatic(typeof(Person), "Title", "Fabrikam CEO"); | |
Console.WriteLine($"Person name after set: {Person.Title}"); | |
Console.WriteLine($"Person name using exp: {ExpressionGetFieldStatic(typeof(Person), "Title")}"); | |
Console.WriteLine(); | |
Console.WriteLine("---------- Instance set/get using expression on fields ----------"); | |
Console.WriteLine($"App name before set: {aid.Desc}"); | |
Console.WriteLine($"App name using exp: {ExpressionGetFieldInstance(aid, "Desc")}"); | |
ExpressionSetFieldInstance(aid, "Desc", "Decentralized social network"); | |
Console.WriteLine($"App name after set: {aid.Desc}"); | |
Console.WriteLine($"App name using exp: {ExpressionGetFieldInstance(aid, "Desc")}"); | |
Console.WriteLine(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment