DynamicPropertyAccessor Expression lambda


namespace ConsoleApplication
{
    using System;
    using System.Linq;
    using Microshaoft;
    using Test.Share;
    public class Class1
    {
        //[STAThread]
        static void Main(string[] args)
        {
            var c = "Test.Share.ComplexType";
            var assembly = AppDomain.CurrentDomain.GetAssemblies().First
                                                                    (
                                                                        (a) =>
                                                                        {
                                                                            return a.GetTypes().Any
                                                                                                (
                                                                                                    (t) =>
                                                                                                    {
                                                                                                        return (t.FullName == c);
                                                                                                    }
                                                                                                );
                                                                        }
                                                                    );
            ComplexType.F2 = "01234";
            var o = new ComplexType();
            o.F1 = "56789";
            var typeName = o.GetType().FullName;
            //=======================================================================================
            var getter1 = DynamicPropertyAccessor.CreateGetStaticPropertyValueFunc(typeName, "f2");
            var v1 = getter1();
            Console.WriteLine(v1);
            //=======================================================================================
            var getter2 = DynamicPropertyAccessor.CreateGetStaticPropertyValueFunc<string>(typeName, "f2");
            string v2 = getter2();
            Console.WriteLine(v2);
            //=======================================================================================
            var getter3 = DynamicPropertyAccessor.CreateGetPropertyValueFunc(typeName, "f1");
            var v3 = getter3(o);
            Console.WriteLine(v3);
            //=======================================================================================
            var getter4 = DynamicPropertyAccessor.CreateGetPropertyValueFunc<string>(typeName, "f1");
            var v4 = getter4(o);
            Console.WriteLine(v4);
            //=======================================================================================
            var setter1 = DynamicPropertyAccessor.CreateSetStaticPropertyValueAction(typeName, "f2");
            setter1("ABCD");
            v1 = getter1();
            Console.WriteLine(v1);
            v2 = getter2();
            Console.WriteLine(v2);
            //=======================================================================================
            var setter2 = DynamicPropertyAccessor.CreateSetStaticPropertyValueAction<string>(typeName, "f2");
            setter2("EFFGH");
            v1 = getter1();
            Console.WriteLine(v1);
            v2 = getter2();
            Console.WriteLine(v2);
            //=======================================================================================
            var setter3 = DynamicPropertyAccessor.CreateSetPropertyValueAction(typeName, "f1");
            setter3(o, "IJKL");
            v3 = getter3(o);
            Console.WriteLine(v3);
            v4 = getter4(o);
            Console.WriteLine(v4);
            //=======================================================================================
            var setter4 = DynamicPropertyAccessor.CreateSetPropertyValueAction<string>(typeName, "f1");
            setter4(o, "MNOP");
            v3 = getter3(o);
            Console.WriteLine(v3);
            v4 = getter4(o);
            Console.WriteLine(v4);
            //=======================================================================================
            Console.ReadLine();
        }
    }
}
namespace Test.Share
{
    using System.Threading;
    public class ComplexType
    {
        public string F1
        {
            get;
            set;
        }
        public static string _f2;
        public static string F2
        {
            get
            {
                return _f2;
            }
            set
            {
                Interlocked.Exchange<string>(ref _f2, value);
            }
        }
    }
}
namespace Microshaoft
{
    using System;
    using System.Linq;
    using System.Linq.Expressions;
    using System.Reflection;
    public class DynamicPropertyAccessor
    {
        private static Assembly GetAssemblyByTypeName(string typeName)
        {
            return AppDomain.CurrentDomain.GetAssemblies().First
                                                        (
                                                            (a) =>
                                                            {
                                                                return a.GetTypes().Any
                                                                                    (
                                                                                        (t) =>
                                                                                        {
                                                                                            return (t.FullName == typeName);
                                                                                        }
                                                                                    );
                                                            }
                                                        );
        }
        public static Func<object, object> CreateGetPropertyValueFunc(string typeName, string propertyName, bool isTypeFromAssembly = false)
        {
            Type type;
            if (isTypeFromAssembly)
            {
                var assembly = GetAssemblyByTypeName(typeName);
                type = assembly.GetType(typeName);
            }
            else
            {
                type = Type.GetType(typeName);
            }
            return CreateGetPropertyValueFunc(type, propertyName);
        }
        public static Func<object, object> CreateGetPropertyValueFunc(Type type, string propertyName)
        {
            var target = Expression.Parameter(typeof(object));
            var castTarget = Expression.Convert(target, type);
            var getPropertyValue = Expression.Property(castTarget, propertyName);
            var castPropertyValue = Expression.Convert(getPropertyValue, typeof(object));
            var lambda = Expression.Lambda<Func<object, object>>(castPropertyValue, target);
            return lambda.Compile();
        }
        public static Func<object, TProperty> CreateGetPropertyValueFunc<TProperty>(string typeName, string propertyName, bool isTypeFromAssembly = false)
        {
            Type type;
            if (isTypeFromAssembly)
            {
                var assembly = GetAssemblyByTypeName(typeName);
                type = assembly.GetType(typeName);
            }
            else
            {
                type = Type.GetType(typeName);
            }
            return CreateGetPropertyValueFunc<TProperty>(type, propertyName);
        }
        public static Func<object, TProperty> CreateGetPropertyValueFunc<TProperty>(Type type, string propertyName)
        {
            var target = Expression.Parameter(typeof(object));
            var castTarget = Expression.Convert(target, type);
            var getPropertyValue = Expression.Property(castTarget, propertyName);
            var lambda = Expression.Lambda<Func<object, TProperty>>(getPropertyValue, target);
            return lambda.Compile();
        }
        public static Func<TProperty> CreateGetStaticPropertyValueFunc<TProperty>(string typeName, string propertyName, bool isTypeFromAssembly = false)
        {
            Type type;
            if (isTypeFromAssembly)
            {
                var assembly = GetAssemblyByTypeName(typeName);
                type = assembly.GetType(typeName);
            }
            else
            {
                type = Type.GetType(typeName);
            }
            return CreateGetStaticPropertyValueFunc<TProperty>(type, propertyName);
        }
        public static Func<TProperty> CreateGetStaticPropertyValueFunc<TProperty>(Type type, string propertyName)
        {
            Func<TProperty> func = null;
            var property = type.GetProperty(propertyName, typeof(TProperty));
            if (property == null)
            {
                property = type.GetProperties().ToList().FirstOrDefault
                                                    (
                                                        (x) =>
                                                        {
                                                            return
                                                                (x.Name.ToLower() == propertyName.ToLower());
                                                        }
                                                    );
            }
            if (property != null)
            {
                var getPropertyValue = Expression.Property(null, property);
                var lambda = Expression.Lambda<Func<TProperty>>(getPropertyValue, null);
                func = lambda.Compile();
            }
            return func;
        }
        public static Func<object> CreateGetStaticPropertyValueFunc(Type type, string propertyName)
        {
            Func<object> func = null;
            var property = type.GetProperty(propertyName);
            if (property == null)
            {
                property = type.GetProperties().ToList().FirstOrDefault
                                                    (
                                                        (x) =>
                                                        {
                                                            return
                                                                (x.Name.ToLower() == propertyName.ToLower());
                                                        }
                                                    );
            }
            if (property != null)
            {
                var getPropertyValue = Expression.Property(null, property);
                var castPropertyValue = Expression.Convert(getPropertyValue, typeof(object));
                var lambda = Expression.Lambda<Func<object>>(castPropertyValue, null);
                func = lambda.Compile();
            }
            return func;
        }
        public static Func<object> CreateGetStaticPropertyValueFunc(string typeName, string propertyName, bool isTypeFromAssembly = false)
        {
            Type type;
            if (isTypeFromAssembly)
            {
                var assembly = GetAssemblyByTypeName(typeName);
                type = assembly.GetType(typeName);
            }
            else
            {
                type = Type.GetType(typeName);
            }
            return CreateGetStaticPropertyValueFunc(type, propertyName);
        }
        public static Action<object, object> CreateSetPropertyValueAction(Type type, string propertyName)
        {
            Action<object, object> action = null;
            var property = type.GetProperty(propertyName);
            if (property == null)
            {
                property = type.GetProperties().ToList().FirstOrDefault
                                                    (
                                                        (x) =>
                                                        {
                                                            return
                                                                (x.Name.ToLower() == propertyName.ToLower());
                                                        }
                                                    );
            }
            if (property != null)
            {
                var target = Expression.Parameter(typeof(object));
                var propertyValue = Expression.Parameter(typeof(object));
                var castTarget = Expression.Convert(target, type);
                var castPropertyValue = Expression.Convert(propertyValue, property.PropertyType);
                var getSetMethod = property.GetSetMethod();
                if (getSetMethod == null)
                {
                    getSetMethod = property.GetSetMethod(true);
                }
                var call = Expression.Call(castTarget, getSetMethod, castPropertyValue);
                var lambda = Expression.Lambda<Action<object, object>>(call, target, propertyValue);
                action = lambda.Compile();
            }
            return action;
        }
        public static Action<object, object> CreateSetPropertyValueAction(string typeName, string propertyName, bool isTypeFromAssembly = false)
        {
            Type type;
            if (isTypeFromAssembly)
            {
                var assembly = GetAssemblyByTypeName(typeName);
                type = assembly.GetType(typeName);
            }
            else
            {
                type = Type.GetType(typeName);
            }
            return CreateSetPropertyValueAction(type, propertyName);
        }
        public static Action<object, TProperty> CreateSetPropertyValueAction<TProperty>(Type type, string propertyName)
        {
            Action<object, TProperty> action = null;
            var property = type.GetProperty(propertyName);
            if (property == null)
            {
                property = type.GetProperties().ToList().FirstOrDefault
                                                    (
                                                        (x) =>
                                                        {
                                                            return
                                                                (x.Name.ToLower() == propertyName.ToLower());
                                                        }
                                                    );
            }
            if (property != null)
            {
                var target = Expression.Parameter(typeof(object));
                var propertyValue = Expression.Parameter(typeof(TProperty));
                var castTarget = Expression.Convert(target, type);
                var castPropertyValue = Expression.Convert(propertyValue, property.PropertyType);
                var getSetMethod = property.GetSetMethod();
                if (getSetMethod == null)
                {
                    getSetMethod = property.GetSetMethod(true);
                }
                var call = Expression.Call(castTarget, getSetMethod, castPropertyValue);
                var lambda = Expression.Lambda<Action<object, TProperty>>(call, target, propertyValue);
                action = lambda.Compile();
            }
            return action; 
        }
        public static Action<object, TProperty> CreateSetPropertyValueAction<TProperty>(string typeName, string propertyName, bool isTypeFromAssembly = false)
        {
            Type type;
            if (isTypeFromAssembly)
            {
                var assembly = GetAssemblyByTypeName(typeName);
                type = assembly.GetType(typeName);
            }
            else
            {
                type = Type.GetType(typeName);
            }
            return CreateSetPropertyValueAction<TProperty>(type, propertyName);
        }
        public static Action<object> CreateSetStaticPropertyValueAction(Type type, string propertyName)
        {
            Action<object> action = null;
            var property = type.GetProperty(propertyName);
            if (property == null)
            {
                property = type.GetProperties().ToList().FirstOrDefault
                                                    (
                                                        (x) =>
                                                        {
                                                            return
                                                                (x.Name.ToLower() == propertyName.ToLower());
                                                        }
                                                    );
            }
            if (property != null)
            {
                var propertyValue = Expression.Parameter(typeof(object));
                var castPropertyValue = Expression.Convert(propertyValue, property.PropertyType);
                var getSetMethod = property.GetSetMethod();
                if (getSetMethod == null)
                {
                    getSetMethod = property.GetSetMethod(true);
                }
                var call = Expression.Call(null, getSetMethod, castPropertyValue);
                var lambda = Expression.Lambda<Action<object>>(call, propertyValue);
                action = lambda.Compile();
            }
            return action;
        }
        public static Action<object> CreateSetStaticPropertyValueAction(string typeName, string propertyName, bool isTypeFromAssembly = false)
        {
            Type type;
            if (isTypeFromAssembly)
            {
                var assembly = GetAssemblyByTypeName(typeName);
                type = assembly.GetType(typeName);
            }
            else
            {
                type = Type.GetType(typeName);
            }
            return CreateSetStaticPropertyValueAction(type, propertyName);
        }
        public static Action<TProperty> CreateSetStaticPropertyValueAction<TProperty>(Type type, string propertyName)
        {
            Action<TProperty> action = null;
            var property = type.GetProperty(propertyName);
            if (property == null)
            {
                property = type.GetProperties().ToList().FirstOrDefault
                                                    (
                                                        (x) =>
                                                        {
                                                            return
                                                                (x.Name.ToLower() == propertyName.ToLower());
                                                        }
                                                    );
            }
            if (property != null)
            {
                var propertyValue = Expression.Parameter(typeof(TProperty));
                //var castPropertyValue = Expression.Convert(propertyValue, property.PropertyType);
                var getSetMethod = property.GetSetMethod();
                if (getSetMethod == null)
                {
                    getSetMethod = property.GetSetMethod(true);
                }
                var call = Expression.Call(null, getSetMethod, propertyValue);
                var lambda = Expression.Lambda<Action<TProperty>>(call, propertyValue);
                action = lambda.Compile();
            }
            return action;
        }
        public static Action<TProperty> CreateSetStaticPropertyValueAction<TProperty>(string typeName, string propertyName, bool isTypeFromAssembly = false)
        {
            Type type;
            if (isTypeFromAssembly)
            {
                var assembly = GetAssemblyByTypeName(typeName);
                type = assembly.GetType(typeName);
            }
            else
            {
                type = Type.GetType(typeName);
            }
            return CreateSetStaticPropertyValueAction<TProperty>(type, propertyName);
        }
    }
}

原文地址:https://www.cnblogs.com/Microshaoft/p/2459867.html