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)))));
}
我希望能够通过。
调用此函数var source = new MyClass();
var other = new MyClass();
source.Compare<MyClass>(other, ()=>SkipProperty1, ()=>SkipProperty2);
问题是()=&gt; SkipProperty1和()=&gt; SkipProperty2不是MyClass类型。 我需要:
Compare <A,B,C,D...>
params Expression<Func<T>>[] where T is A,B,C,D,E...
我用流利的语法查看了AutoMapper。
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()));
- 我可以更改比较的签名以使该功能有效吗?
- 还有其他解决方法吗?例如,使用流畅的语法
注意我不想将属性名称作为字符串发送。
答案 0 :(得分:2)
一种选择是将param
参数的签名更改为返回object
的lambda表达式。像这样:
public static bool Compare<T>
(this T source, T other, params Expression<Func<object>>[] propertiesToSkip)
这应该可以正常工作,因为任何.NET类型都可以强制转换或加框到对象。您需要稍微调整代码以从lambda表达式中提取PropertyInfo
(因为会有额外的装箱或强制转换)。
使用流畅的语法也应该有效。你需要一些类型来传递:
class SkipComparison<T> {
public T Source { get; set; }
public T Other { get; set; }
public List<PropertyInfo> PropertiesToSkip { get; set; }
public SkipComparison<T> Skip<R>(Expression<Func<R>> f)
// TODO: Extract property info, add it to
// 'PropertiesToSkip' and 'return this;'
public bool Run()
// TODO: Actually perform the comparison here
}
您的Compare
方法会返回此类的新实例,只设置Source
和Other
,您将使用Skip
方法添加其他属性跳过。