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); }
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); }