开发者

Is it possible to have an array of unknown types?

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<MyCl开发者_StackOverflow中文版ass>(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 param arguments to be lambda expressions that return object. Something like this:

public static bool Compare<T>
  (this T source, T other, params Expression<Func<object>>[] propertiesToSkip)

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 PropertyInfo from 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:

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
}

Your Compare method will return a new instance of this class with just Source and Other set and you'll use the Skip method to add additional properties to be skipped.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜