Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public static Expression<Func<Foo, FooEditDto>> EditDtoSelector()
- {
- return f => new FooEditDto
- {
- PropertyA = f.PropertyA,
- PropertyB = f.PropertyB,
- PropertyC = f.PropertyC,
- PropertyD = f.PropertyD,
- PropertyE = f.PropertyE
- };
- }
- public static Expression<Func<Foo, FooListDto>> ListDtoSelector()
- {
- return f => new FooDto
- {
- PropertyA = f.PropertyA,
- PropertyB = f.PropertyB,
- PropertyC = f.PropertyC
- };
- }
- class FooDto
- { public FooDto(Bar a, Bar b, Bar c)
- { PropertyA = a;
- PropertyB = b;
- PropertyC = c;
- }
- public Bar PropertyA {get;set;}
- public Bar PropertyB {get;set;}
- public Bar PropertyC {get;set;}
- }
- class FooEditDto : FooDto
- { public FooEditDto(Bar a, Bar b, Bar c) : base(a,b,c)
- public Bar PropertyD {get;set;}
- public Bar PropertyE {get;set;}
- }
- public static Expression<Func<Foo, FooEditDto>> EditDtoSelector()
- {
- return f => new FooEditDto(f.PropertyA,f.PropertyB,f.PropertyC)
- {
- PropertyD = f.PropertyD,
- PropertyE = f.PropertyE
- };
- }
- public static Expression<Func<Foo, FooEditDto>> EditDtoSelector()
- {
- return f => MagicCopier<FooEditDto>.Copy(new {
- f.PropertyA, f.PropertyB, f.PropertyC, f.PropertyD, f.PropertyC
- });
- }
- /// <summary>
- /// Generic class which copies to its target type from a source
- /// type specified in the Copy method. The types are specified
- /// separately to take advantage of type inference on generic
- /// method arguments.
- /// </summary>
- public static class PropertyCopy<TTarget> where TTarget : class, new()
- {
- /// <summary>
- /// Copies all readable properties from the source to a new instance
- /// of TTarget.
- /// </summary>
- public static TTarget CopyFrom<TSource>(TSource source) where TSource : class
- {
- return PropertyCopier<TSource>.Copy(source);
- }
- /// <summary>
- /// Static class to efficiently store the compiled delegate which can
- /// do the copying. We need a bit of work to ensure that exceptions are
- /// appropriately propagated, as the exception is generated at type initialization
- /// time, but we wish it to be thrown as an ArgumentException.
- /// </summary>
- private static class PropertyCopier<TSource> where TSource : class
- {
- private static readonly Func<TSource, TTarget> copier;
- private static readonly Exception initializationException;
- internal static TTarget Copy(TSource source)
- {
- if (initializationException != null)
- {
- throw initializationException;
- }
- if (source == null)
- {
- throw new ArgumentNullException("source");
- }
- return copier(source);
- }
- static PropertyCopier()
- {
- try
- {
- copier = BuildCopier();
- initializationException = null;
- }
- catch (Exception e)
- {
- copier = null;
- initializationException = e;
- }
- }
- private static Func<TSource, TTarget> BuildCopier()
- {
- ParameterExpression sourceParameter = Expression.Parameter(typeof(TSource), "source");
- var bindings = new List<MemberBinding>();
- foreach (PropertyInfo sourceProperty in typeof(TSource).GetProperties())
- {
- if (!sourceProperty.CanRead)
- {
- continue;
- }
- PropertyInfo targetProperty = typeof(TTarget).GetProperty(sourceProperty.Name);
- if (targetProperty == null)
- {
- throw new ArgumentException("Property " + sourceProperty.Name
- + " is not present and accessible in " + typeof(TTarget).FullName);
- }
- if (!targetProperty.CanWrite)
- {
- throw new ArgumentException("Property " + sourceProperty.Name
- + " is not writable in " + typeof(TTarget).FullName);
- }
- if (!targetProperty.PropertyType.IsAssignableFrom(sourceProperty.PropertyType))
- {
- throw new ArgumentException("Property " + sourceProperty.Name
- + " has an incompatible type in " + typeof(TTarget).FullName);
- }
- bindings.Add(Expression.Bind(targetProperty, Expression.Property(sourceParameter, sourceProperty)));
- }
- Expression initializer = Expression.MemberInit(Expression.New(typeof(TTarget)), bindings);
- return Expression.Lambda<Func<TSource,TTarget>>(initializer, sourceParameter).Compile();
- }
- }
- TargetType target = PropertyCopy<TargetType>.CopyFrom(new { First="Foo", Second="Bar" });
- public static Expression<Func<Foo,T>>
- GetSelector<T>(Expression<Func<Foo,T>> f)
- { return f;
- }
- /* ... */
- var expr = GetSelector(f => new{f.PropertyA,f.PropertyB,f.PropertyC});
Add Comment
Please, Sign In to add comment