3

Well recently i came up with an idea (that i really don't know whether it would exist or even work) of automatic updating class's properties using an modified instance of it. And to make my idea a little bit more clear, i will explain it in the code below.

//The first (Main) instance of the class
Employee carl = new Employee();
carl.Name = "Carl";
carl.Age = 20;
carl.Salary = 7000;

//Here is the same employee data collected from the database a year after...
Employee carl_one_year_later = new Employee();
carl_one_year_later.Age = 21;
carl_one_year_later.Salary = 10000;

//Here comes the idea... I wanna dynamically merge the new collected data to the current main instance of the employee, without missing out the unupdated data ex : his name
employee1 = employee2; //using this seems to overwrite the Name Field with null...

Someone might say you can simply achieve this by doing this:

carl.Age = carl_one_year_later.Age;
carl.Salary = carl_one_year_later.Salary;

However, i want a dynamic way to just do this in 1 line of code and let C# handle the property set for me, also it may come in handy if we have a massive class that we don't want to set it's properties every time it is updated one by one.

NB: I hope i succeed in providing a clear image of my idea, and if you find any problem understanding what exactly do i need, just let me know.

Daniel Eugen
  • 2,582
  • 6
  • 31
  • 53
  • how about using reflection to iterate over properties and set those except which are null or default? – gp. Oct 16 '13 at 03:07
  • @gp.: Sorry i don't have experience with reflection, and if it really does what i am talking about, and in 1 line or (the less as possible). You may provide me with an detailed answer about how i could achieve it. – Daniel Eugen Oct 16 '13 at 03:09
  • Also, don't forget to take into account that as you say, i only want to get from the updated class the values that are not (null, or default) and set those value to the default main class... – Daniel Eugen Oct 16 '13 at 03:11
  • We used to have this in COBOL, and I sometimes wish we still did. It was called [MOVE CORRESPONDING](http://stackoverflow.com/questions/719135/whats-the-bright-side-of-cobol/719176#719176). – John Saunders Oct 16 '13 at 04:19

5 Answers5

2
using System;
using System.Reflection;

public class Test
{
    public class Employee
    {
        public String Name{get;set;}
        public int Age{get;set;}
        public int Salary{get;set;}
    }
    public static void Main()
    {
        Employee e1 = new Employee{Name="Old", Age=20, Salary=1000};
        Employee e2 = new Employee{Age=30, Salary=5000};

        Copy(e2, e1);

        Console.WriteLine(e1.Name+" "+ e1.Age+" "+e1.Salary );
    }

    public static void Copy<T>(T from, T to)
    {
        Type t = typeof (T);
        PropertyInfo[] props = t.GetProperties(BindingFlags.Public | BindingFlags.Instance);
        foreach (PropertyInfo p in props) {
            if (!p.CanRead || !p.CanWrite) continue;

            object val = p.GetGetMethod().Invoke(from, null);
            object defaultVal = p.PropertyType.IsValueType ? Activator.CreateInstance(p.PropertyType) : null;
            if (null != defaultVal && !val.Equals(defaultVal)) {
                p.GetSetMethod().Invoke(to, new[] {val});
            }
        }
    }
}
Daniel Eugen
  • 2,582
  • 6
  • 31
  • 53
gp.
  • 7,751
  • 3
  • 38
  • 38
1

You can make a CopyTo extension method, like so:

public static class ObjectExtensions
{
    public static void CopyTo<T>(this T fromObj, T toObj)
    {
        foreach(var p in typeof(T).GetProperties()) 
        {
            p.SetValue(toObj, p.GetValue(fromObj, null), null);
        }
    }
}

And call it like:

carl_one_year_later.CopyTo(carl);

Although, to be honest, there's a few more checks that should be made, and you'd be better off using something like AutoMapper instead.

rossipedia
  • 52,494
  • 10
  • 88
  • 90
0

Checkout ICloneable OR MemberwiseClone (unless you need to do a deep copy. Then check out a object mapper like Automapper, ValueInjecter or write your own custom object serialization hydrater)

http://msdn.microsoft.com/en-us/library/system.object.memberwiseclone.aspx

The MemberwiseClone method creates a shallow copy by creating a new object, and then copying the nonstatic fields of the current object to the new object.

http://msdn.microsoft.com/en-us/library/system.icloneable.aspx

Alternatives to AutoMapper

Community
  • 1
  • 1
Chris McKelt
  • 1,338
  • 2
  • 17
  • 36
0
public static class ObjectExtensions
    {
        public static void CopyTo<T>(this T fromObj, T toObj)
        {
            foreach (var p in typeof(T).GetProperties())
            {
                if(p.GetValue(fromObj) == null)
                {
                    continue;
                }
                p.SetValue(toObj, p.GetValue(fromObj, null), null);
            }
        }
    }

Same as the above answer but just added "if" in "foreach" to skip the null values

Hinco
  • 1
-1

The idea itself seems odd to me..

I, myself, would just rather do :

//The first (Main) instance of the class
Employee carl = new Employee();
carl.Name = "Carl";
carl.Age = 20;
carl.Salary = 7000;

//Here we get Carl from the database
Employee carl = GetFromDatabase("Carl") //Illustration
carl.Age = 21;
carl.Salary = 10000;

Your code is like saying nowadays Carl and next year Carl is a completely different person, and coincidentally having all those same attributes.

Although if it really needs to be done, I do tend to prefer Automapper..

Samuel Adam
  • 1,307
  • 4
  • 26
  • 45