C# || How To Copy All Properties & Fields From One Object To Another Using C#
The following is a module with functions which demonstrates how to copy all properties and fields from one object to another using C#.
The function demonstrated on this page is a generic extension method which uses reflection to copy all the matching properties and fields from one object to another.
This function works on both structure and class object fields and properties.
The two objects do not have to be the same type. Only the matching properties and fields are copied.
1. Copy Properties & Fields
The example below demonstrates the use of ‘Utils.Objects.CopyPropsTo‘ to copy all the matching properties and fields from the source object to the destination object.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
// Copy Properties & Fields using Utils; public class Part { public string PartName { get; set; } public int PartId { get; set; } } public struct Part2 { public string PartName { get; set; } public int PartId; } // Declare source object var part1 = new Part() { PartName = "crank arm", PartId = 1234 }; // Declare destination object var part2 = new Part2(); // Copy matching properties and fields to destination part1.CopyPropsTo(ref part2); // Display information Console.WriteLine($"{part2.PartId} - {part2.PartName}"); // expected output: /* 1234 - crank arm */ |
2. Utils Namespace
The following is the Utils Namespace. Include this in your project to start using!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
// ============================================================================ // Author: Kenneth Perkins // Date: May 11, 2021 // Taken From: http://programmingnotes.org/ // File: Utils.cs // Description: Handles general utility functions // ============================================================================ using System; using System.Collections.Generic; using System.Linq; namespace Utils { public static class Objects { /// <summary> /// Copies all the matching properties and fields from 'source' to 'destination' /// </summary> /// <param name="source">The source object to copy from</param> /// <param name="destination">The destination object to copy to</param> public static void CopyPropsTo<T1, T2>(this T1 source, ref T2 destination) { var sourceMembers = GetMembers(source.GetType()); var destinationMembers = GetMembers(destination.GetType()); // Copy data from source to destination foreach (var sourceMember in sourceMembers) { if (!CanRead(sourceMember)) { continue; } var destinationMember = destinationMembers.FirstOrDefault(x => x.Name.ToLower() == sourceMember.Name.ToLower()); if (destinationMember == null || !CanWrite(destinationMember)) { continue; } SetObjectValue(ref destination, destinationMember, GetMemberValue(source, sourceMember)); } } private static void SetObjectValue<T>(ref T obj, System.Reflection.MemberInfo member, object value) { // Boxing method used for modifying structures var boxed = obj.GetType().IsValueType ? (object)obj : obj; SetMemberValue(ref boxed, member, value); obj = (T)boxed; } private static void SetMemberValue<T>(ref T obj, System.Reflection.MemberInfo member, object value) { if (IsProperty(member)) { var prop = (System.Reflection.PropertyInfo)member; if (prop.SetMethod != null) { prop.SetValue(obj, value); } } else if (IsField(member)) { var field = (System.Reflection.FieldInfo)member; field.SetValue(obj, value); } } private static object GetMemberValue(object obj, System.Reflection.MemberInfo member) { object result = null; if (IsProperty(member)) { var prop = (System.Reflection.PropertyInfo)member; result = prop.GetValue(obj, prop.GetIndexParameters().Count() == 1 ? new object[] { null } : null); } else if (IsField(member)) { var field = (System.Reflection.FieldInfo)member; result = field.GetValue(obj); } return result; } private static bool CanWrite(System.Reflection.MemberInfo member) { return IsProperty(member) ? ((System.Reflection.PropertyInfo)member).CanWrite : IsField(member); } private static bool CanRead(System.Reflection.MemberInfo member) { return IsProperty(member) ? ((System.Reflection.PropertyInfo)member).CanRead : IsField(member); } private static bool IsProperty(System.Reflection.MemberInfo member) { return IsType(member.GetType(), typeof(System.Reflection.PropertyInfo)); } private static bool IsField(System.Reflection.MemberInfo member) { return IsType(member.GetType(), typeof(System.Reflection.FieldInfo)); } private static bool IsType(System.Type type, System.Type targetType) { return type.Equals(targetType) || type.IsSubclassOf(targetType); } private static List<System.Reflection.MemberInfo> GetMembers(System.Type type) { var flags = System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic; var members = new List<System.Reflection.MemberInfo>(); members.AddRange(type.GetProperties(flags)); members.AddRange(type.GetFields(flags)); return members; } } }// http://programmingnotes.org/ |
3. More Examples
Below are more examples demonstrating the use of the ‘Utils‘ Namespace. Don’t forget to include the module when running the examples!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
// ============================================================================ // Author: Kenneth Perkins // Date: May 11, 2021 // Taken From: http://programmingnotes.org/ // File: Program.cs // Description: The following demonstrates the use of the Utils Namespace // ============================================================================ using System; using System.Diagnostics; using System.Collections.Generic; using Utils; public class Program { public class Part { public string PartName { get; set; } public int PartId { get; set; } } public struct Part2 { public string PartName { get; set; } public int PartId; } static void Main(string[] args) { try { // Declare source object var part1 = new Part() { PartName = "crank arm", PartId = 1234 }; // Declare destination object var part2 = new Part2(); // Copy matching properties and fields to destination part1.CopyPropsTo(ref part2); // Display information Console.WriteLine($"{part2.PartId} - {part2.PartName}"); } catch (Exception ex) { Display(ex.ToString()); } finally { Console.ReadLine(); } } static void Display(string message) { Console.WriteLine(message); Debug.Print(message); } }// http://programmingnotes.org/ |
QUICK NOTES:
The highlighted lines are sections of interest to look out for.
The code is heavily commented, so no further insight is necessary. If you have any questions, feel free to leave a comment below.
Leave a Reply