• 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);
            }
        }
    }
    
    
  • 相关阅读:
    Linux 下 Lua 与 LuaSQL 模块安装
    js学习笔记27----键盘事件
    js学习笔记26----事件冒泡,事件捕获
    js学习笔记25----Event对象
    js学习笔记24----焦点事件
    js学习笔记23----窗口尺寸及窗口事件
    js学习笔记22----BOM属性和方法
    VS Code 常用快捷键
    你不知道的JavaScript学习笔记1——作用域
    三种CSS方法实现loadingh点点点的效果
  • 原文地址:https://www.cnblogs.com/Microshaoft/p/2459867.html
Copyright © 2020-2023  润新知