How to copy value from class X to class Y with the same property name in c#?

后端 未结 5 753
灰色年华
灰色年华 2020-11-28 08:49

Suppose I have two classes:

public class Student
{
    public int Id {get; set;}
    public string Name {get; set;}
    public IList Courses{ g         


        
5条回答
  •  一向
    一向 (楼主)
    2020-11-28 09:25

    Ok I just looked up the MiscUtil that Marc posted about and its just awesome. I hope mark doesn't mind me adding the code here.

    using System;
    using System.Collections;
    using System.Collections.Specialized;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Reflection;
    using System.ComponentModel;
    using System.Linq.Expressions;
    
    namespace ConsoleApplication1
    {
        class Program
        {
            public class Student
            {
                public int Id { get; set; }
                public string Name { get; set; }
                public IList Courses { get; set; }
                public static implicit operator Student(StudentDTO studentDTO)
                {
                    return PropertyCopy.CopyFrom(studentDTO);
                }
            }
    
            public class StudentDTO
            {
                public int Id { get; set; }
                public string Name { get; set; }
                public IList Courses { get; set; }
                public static implicit operator StudentDTO(Student student)
                {
                    return PropertyCopy.CopyFrom(student);
                }
            }
    
    
            static void Main(string[] args)
            {
                Student _student = new Student();
                _student.Id = 1;
                _student.Name = "Timmmmmmmmaaaahhhh";
                _student.Courses = new List();
                _student.Courses.Add(101);
                _student.Courses.Add(121);
    
                StudentDTO itemT = _student;
    
                Console.WriteLine(itemT.Id);
                Console.WriteLine(itemT.Name);
                Console.WriteLine(itemT.Courses.Count);
            }
    
    
        }
    
    
        // COOLEST PIECE OF CODE FROM - http://www.yoda.arachsys.com/csharp/miscutil/
    
        /// 
        /// 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.
        /// 
        public class PropertyCopy where TTarget : class, new()
        {
            /// 
            /// Copies all readable properties from the source to a new instance
            /// of TTarget.
            /// 
            public static TTarget CopyFrom(TSource source) where TSource : class
            {
                return PropertyCopier.Copy(source);
            }
    
            /// 
            /// 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.
            /// 
            private static class PropertyCopier where TSource : class
            {
                private static readonly Func 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 BuildCopier()
                {
                    ParameterExpression sourceParameter = Expression.Parameter(typeof(TSource), "source");
                    var bindings = new List();
                    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>(initializer, sourceParameter).Compile();
                }
            }
        }
    
    }
    

提交回复
热议问题