示例#1
0
        public T Ctor <T>(params object[] args)
        {
            //where T : new()
            //if (args == null || args.Length == 0)
            //    return new T();

            var             clazz       = typeof(T);
            var             argTypes    = args.Select(e => e.GetType()).ToArray();
            var             key         = KeyMaker.AddHashCode <Type>(clazz, KeyMaker.GetHashCode(argTypes));
            ConstructorInfo constructor = null;

            if (!_constructors.TryGetValue(key, out constructor))
            {
                constructor = clazz.GetConstructor(argTypes);
                _constructors.Add(key, constructor);
            }
            if (constructor == null)
            {
                StringBuilder argMsg = new StringBuilder("(");
                argTypes.ForEach(t => argMsg.Append(t.Name + ","));
                if (argMsg.Length > 0)
                {
                    argMsg.Replace(',', ')', argMsg.Length - 1, 1);
                }
                throw new ArgumentException("typeof(" + clazz.Name + ") has no constructor with argumtens " + argMsg);
            }
            T result = (T)constructor.Invoke(args);

            return(result);
        }
示例#2
0
        public T Copy(T source, T sink)
        {
            if (source == null || sink == null)
            {
                return(sink);
            }
            var clazz      = typeof(T);
            var sourceType = source.GetType();
            var sinkType   = sink.GetType();

            var key = KeyMaker.GetHashCode(clazz, sourceType, sinkType);
            //var delegateType = typeof(Action<,>).MakeGenericType(sourceType, sinkType);

            Delegate copyAction = null;

            if (!copyActionCache.TryGetValue(key, out copyAction))
            {
                var delegateType = typeof(Action <,>).MakeGenericType(sourceType, sinkType);
                var sourceExpr   = Expression.Variable(sourceType, "source");
                var destExpr     = Expression.Variable(sinkType, "sink");

                var memberFilter = MemberFilter();
                cache.AddType(sinkType, memberFilter);
                var sourceMembers = cache.Members(sourceType, memberFilter);

                var paras            = new ParameterExpression[] { sourceExpr, destExpr };
                var blockExpressions = new List <Expression>();
                try {
                    foreach (var sourceInfo in sourceMembers)
                    {
                        if (cache.ValidMember(sinkType, sourceInfo.PropertyType, sourceInfo.Name))
                        {
                            var sourceMember = Expression.Property(sourceExpr, sourceInfo);
                            var destInfo     = sinkType.GetProperty(sourceInfo.Name, sourceInfo.PropertyType);
                            var destMember   = Expression.Property(destExpr, destInfo);
                            blockExpressions.Add(Expression.Assign(destMember, sourceMember));
                        }
                    }

                    var copyExpression = Expression.Lambda(delegateType, Expression.Block(blockExpressions), paras);
                    copyAction = copyExpression.Compile();
                } catch (Exception ex) {
                    // Trace.WriteLine(this.GetType().Name + "-Error. Fallback to Copy3");
                    // return Copy3(source, sink);
                    throw ex;
                }
                copyActionCache.Add(key, copyAction);
            }
            copyAction.DynamicInvoke(new object[] { source, sink });
            // this is slower:
            //delegateType.InvokeMember("Invoke",
            //BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod,
            //null, copyAction, new object[] { source, sink });

            return(sink);
        }