I'm working on a method that dynamically copies variables of the same name and type (not necessarily from the same class). I don't want to blindly copy everything because an admin of the site has that ability while a user doesn't. For example, here are some of the event objects:
public class Event
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime EventDate { get; set; }
public int Organization { get; set; }
public string Location { get; set; }
public int SpotsAvailable { get; set; }
public int CreatedBy { get; set; }
public DateTime CreatedDate { get; set; }
public int ModifiedBy { get; set; }
public DateTime ModifiedDate { get; set; }
public int ApprovedBy { get; set; }
public DateTime ApprovedDate { get; set; }
public bool AutomaticallyApproved { get; set; }
}
What I want to do is have a generic method that only clones the objects I want, ignoring an array of variable names that I want to be left blank or the property's default. Based off of this post I created a method that copies all fields that are named the same and have the same property type and everything works great. Now I want to add a line (if(ignoreObjects.Contains(srcProp.Name))) that can check if the ignore array contains the current property:
public void Clone(ref object destination, object source, object[] ignoreObjects)
{
// Getting the Types of the objects
Type typeDest = destination.GetType();
Type typeSrc = source.GetType();
// Iterate the Properties of the source instance and
// populate them from their desination counterparts
PropertyInfo[] srcProperties = typeSrc.GetProperties();
foreach (PropertyInfo srcProp in srcProperties)
{
if(ignoreObjects.Contains(srcProp.Name))
{
continue;
}
PropertyInfo targetProperty = typeDest.GetProperty(srcProp.Name);
if (targetProperty == null)
{
continue;
}
if (!targetProperty.CanWrite)
{
continue;
}
if (targetProperty.GetSetMethod(true) != null && targetProperty.GetSetMethod(true).IsPrivate)
{
continue;
}
if ((targetProperty.GetSetMethod().Attributes & MethodAttributes.Static) != 0)
{
continue;
}
if (!targetProperty.PropertyType.IsAssignableFrom(srcProp.PropertyType))
{
continue;
}
targetProperty.SetValue(destination, srcProp.GetValue(source, null), null);
}
}
I would ideally call the method above like this:
Clone(ref newEvent, eventInfo, { eventInfo.ApprovedBy, eventInfo.ApprovedDate, eventInfo.Organization, eventInfo.SpotsAvailable } );
Where this would copy all event information from "eventInfo" into "newEvent", ignoring the fields ApprovedBy, ApprovedDate, Organization, and SpotsAvailable.
Is it possible to send a list/array of variables to an ignored array? I can certainly add a "nameof" before each variable to create a string array (ex: nameof(eventInfo.ApprovedBy) ) but I would prefer to just reference the class properties themselves to reduce code.
I've previously used AutoMapper but want to learn if this is possible without any 3rd party tools.