If I have a C# class
public class Foo
{
public int? a { get; set; }
public int? b { get; set; }
}
And two instances of that class
var foo1 = new Foo() { a = 1 };
var foo2 = new Foo() { b = 1 };
How could I copy the values from both objects to create a new instance of Foo
that contained the values from both foo1
and foo2
?
In Javascript this would be as simple as
var foo3 = Object.assign({}, foo1, foo2);
assign() pattern in Node 8.
Object.assign() The Object.assign() method copies all enumerable own properties from one or more source objects to a target object. It returns the modified target object.
Spread in object literals Note that Object.assign() can be used to mutate an object, whereas spread syntax can't. In addition, Object.assign() triggers setters on the target object, whereas spread syntax does not.
By using a separate member method : By using a separate member method also we can initialize objects. A member function of the respective class is created and that is used to assign the initial values to the objects. The below program shows how the array of objects is initialized using a separate member method.
you could create a method which merges objects via reflection. But beware, this is slow an can generally not used in C#.
Care must be taken to skip "empty" properties. In your case these are value types. In my example implementation, every property is skipped, if its the default value of that type (for int this is 0):
public T CreateFromObjects<T>(params T[] sources)
where T : new()
{
var ret = new T();
MergeObjects(ret, sources);
return ret;
}
public void MergeObjects<T>(T target, params T[] sources)
{
Func<PropertyInfo, T, bool> predicate = (p, s) =>
{
if (p.GetValue(s).Equals(GetDefault(p.PropertyType)))
{
return false;
}
return true;
};
MergeObjects(target, predicate, sources);
}
public void MergeObjects<T>(T target, Func<PropertyInfo, T, bool> predicate, params T[] sources)
{
foreach (var propertyInfo in typeof(T).GetProperties().Where(prop => prop.CanRead && prop.CanWrite))
{
foreach (var source in sources)
{
if (predicate(propertyInfo, source))
{
propertyInfo.SetValue(target, propertyInfo.GetValue(source));
}
}
}
}
private static object GetDefault(Type type)
{
if (type.IsValueType)
{
return Activator.CreateInstance(type);
}
return null;
}
usage:
var foo3 = CreateFromObjects(foo1, foo2);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With