public static bool Compare<T>(this T source, T other, params Expression<Func<T>>[] propertiesToSkip)
{
PropertyInfo[] sourceProperties = source.GetType().GetProperties();
List<string> lstPropertiesToSkip = (from x in propertiesToSkip select ((MemberExpression)((UnaryExpression)x.Body).Operand).Member.Name).ToList();
return !(sourceProperties.Any(sourcePropertyInfo => !lstPropertiesToSkip.Contains(sourcePropertyInfo.Name) && (!sourcePropertyInfo.GetValue(source, null).Equals(sourcePropertyInfo.GetValue(other, null)))));
}
I want to be able to call this function by.
var source = new MyClass();
var other = new MyClass();
source.Compare<MyClass>(other, ()=>SkipProperty1, ()=>SkipProperty2);
The problem is ()=>SkipProperty1 and ()=>SkipProperty2 are not of type MyClass.
I need:
Compare <A,B,C,D...>
params Expression<Func<T>>[] where T is A,B,C,D,E...
I have looked at AutoMapper, with fluent syntax.
public IMappingExpression<TSource, TDestination> ForMember(string name, Action<IMemberConfigurationExpression<TSource>> memberOptions);
Mapper.CreateMap<MyClass, MyClass>()
.ForMember(dest => dest.Property1, opt => opt.Ignore())
.ForMember(dest => dest.Property2, opt => opt.Ignore()));
– Can I change the signature of Compare to make the function work?
– Is there other way to solving this? For example using fluent syntax
Note I don’t want to send property names as strings.
One option would be to change the signature of your
paramarguments to be lambda expressions that returnobject. Something like this:This should work fine, because any .NET type can be cast or boxed to object. You’ll need to slightly adjust your code to extract
PropertyInfofrom the lambda expressions (because there will be additional boxing or cast).Using fluent syntax should work as well. You’ll need some type to pass around:
Your
Comparemethod will return a new instance of this class with justSourceandOtherset and you’ll use theSkipmethod to add additional properties to be skipped.