Created
February 6, 2018 19:28
Star
You must be signed in to star a gist
ObjDiffCollector Rev2, With VerificationException in run in value type implicit boxing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
static class ObjDiffCollector<T> | |
{ | |
private delegate DiffEntry DiffDelegate(T x, T y); | |
private static readonly IReadOnlyDictionary<string, DiffDelegate> DicDiffDels; | |
private static PropertyInfo PropertyOf<TClass, TProperty>(Expression<Func<TClass, TProperty>> sele | |
=> (PropertyInfo)((MemberExpression)selector.Body).Member; | |
static ObjDiffCollector() | |
{ | |
var expParamX = Expression.Parameter(typeof(T), "x"); | |
var expParamY = Expression.Parameter(typeof(T), "y"); | |
var propDrName = PropertyOf((DiffEntry x) => x.Prop); | |
var propDrValX = PropertyOf((DiffEntry x) => x.ValX); | |
var propDrValY = PropertyOf((DiffEntry x) => x.ValY); | |
var dic = new Dictionary<string, DiffDelegate>(); | |
var props = typeof(T).GetProperties(); | |
foreach (var info in props) | |
{ | |
var expValX = Expression.MakeMemberAccess(expParamX, info); | |
var expValY = Expression.MakeMemberAccess(expParamY, info); | |
var expEq = Expression.Equal(expValX, expValY); | |
var expNewEntry = Expression.New(typeof(DiffEntry)); | |
var expMemberInitEntry = Expression.MemberInit(expNewEntry, | |
Expression.Bind(propDrName, Expression.Constant(info.Name)), | |
Expression.Bind(propDrValX, expValX), | |
Expression.Bind(propDrValY, expValY)); | |
var expReturn = Expression.Condition(expEq | |
, Expression.Convert(Expression.Constant(null), typeof(DiffEntry)) | |
, expMemberInitEntry); | |
var expLambda = Expression.Lambda<DiffDelegate>(expReturn, expParamX, expParamY); | |
var compiled = expLambda.Compile(); | |
dic[info.Name] = compiled; | |
} | |
DicDiffDels = dic; | |
} | |
public static DiffEntry[] Diff(T x, T y) | |
{ | |
var list = new List<DiffEntry>(DicDiffDels.Count); | |
foreach (var pair in DicDiffDels) | |
{ | |
var r = pair.Value(x, y); | |
if (r != null) list.Add(r); | |
} | |
return list.ToArray(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment