Extend
An extenssion function to work like the extend method of javascript. It takes the object and merge with oder, but only if the property of the other object has value.
Source
public static T Extend<T>(this T target, T source) where T : class
{
var properties =
target.GetType().GetProperties().Where(pi => pi.CanRead && pi.CanWrite);
foreach (var propertyInfo in properties)
{
var targetValue = propertyInfo.GetValue(target, null);
var defaultValue = propertyInfo.PropertyType.GetDefault();
if (targetValue != null && !targetValue.Equals(defaultValue)) continue;
var sourceValue = propertyInfo.GetValue(source, null);
propertyInfo.SetValue(target, sourceValue, null);
}
return target;
}
public static object GetDefault(this Type type)
{
// If no Type was supplied, if the Type was a reference type, or if the Type was a System.Void, return null
if (type == null || !type.IsValueType || type == typeof(void))
return null;
// If the supplied Type has generic parameters, its default value cannot be determined
if (type.ContainsGenericParameters)
{
throw new ArgumentException(
"{" + MethodBase.GetCurrentMethod() + "} Error:\n\nThe supplied value type <" + type +
"> contains generic parameters, so the default value cannot be retrieved");
}
// If the Type is a primitive type, or if it is another publicly-visible value type (i.e. struct), return a
// default instance of the value type
if (type.IsPrimitive || !type.IsNotPublic)
{
try
{
return Activator.CreateInstance(type);
}
catch (Exception e)
{
throw new ArgumentException(
"{" + MethodBase.GetCurrentMethod() +
"} Error:\n\nThe Activator.CreateInstance method could not " +
"create a default instance of the supplied value type <" + type +
"> (Inner Exception message: \"" + e.Message + "\")", e);
}
}
// Fail with exception
throw new ArgumentException("{" + MethodBase.GetCurrentMethod() + "} Error:\n\nThe supplied value type <" +
type +
"> is not a publicly-visible type, so the default value cannot be retrieved");
}
Example
foo = foo.extend(foo2);