public UpdateWithSignature <T> GetGenerator <T>(MethodBase updateMethod) { if (updateMethod == null) { throw new ArgumentNullException("updateMethod"); } var updateMethodDetails = new UpdateMethodSummary <T>(updateMethod); var cachedGenerator = _cache.GetIfAvailable <T>(updateMethodDetails.DeclaringType, updateMethodDetails.UpdateArguments); if (cachedGenerator != null) { return(cachedGenerator); } // In this case, the delegate has a single updateValues reference - an array of update values (so argsIsAnArray is true var sourceParameter = Expression.Parameter(typeof(T), "source"); var argsParameter = Expression.Parameter(typeof(object[]), "args"); var argsIsAnArray = true; var generator = Expression.Lambda <UpdateWithSignature <T> >( GetGeneratorBodyExpression <T>(updateMethodDetails.UpdateArguments, sourceParameter, new[] { argsParameter }, argsIsAnArray), sourceParameter, argsParameter ) .Compile(); _cache.Set <T>(updateMethodDetails.DeclaringType, updateMethodDetails.UpdateArguments, generator); return(generator); }
public TUpdateSignature GetUncachedGeneratorExpression <TUpdateSignature>(MethodBase updateMethod, int numberOfUpdateArguments) { if (updateMethod == null) { throw new ArgumentNullException("updateMethod"); } if (numberOfUpdateArguments <= 0) { throw new ArgumentOutOfRangeException("must be greater than zero", "numberOfUpdateArguments"); } // In this case, the delegate will have one concrete argument per update value (as opposed to a single argument that is an array // of update values), so argsIsAnArray is false) var updateMethodDetails = new UpdateMethodSummary <TSource>(updateMethod); var sourceParameter = Expression.Parameter(typeof(TSource), "source"); var argParameters = Enumerable.Range(0, numberOfUpdateArguments) .Select(i => Expression.Parameter(typeof(object), "arg" + i)) .ToArray(); // Call ToArray() to evaluate this once otherwise the reference won't match when used twice below var argsIsAnArray = false; return (Expression.Lambda <TUpdateSignature>( _updateWitHelper.GetGeneratorBodyExpression <TSource>(updateMethodDetails.UpdateArguments, sourceParameter, argParameters, argsIsAnArray), new[] { sourceParameter }.Concat(argParameters) ) .Compile()); }