in src/WebJobs.Extensions.Http/PropertyHelper.cs [210:251]
private static Func<object, object> MakeFastPropertyGetter(
PropertyInfo propertyInfo,
MethodInfo propertyGetterWrapperMethod,
MethodInfo propertyGetterByRefWrapperMethod)
{
Debug.Assert(propertyInfo != null);
// Must be a generic method with a Func<,> parameter
Debug.Assert(propertyGetterWrapperMethod != null);
Debug.Assert(propertyGetterWrapperMethod.IsGenericMethodDefinition);
Debug.Assert(propertyGetterWrapperMethod.GetParameters().Length == 2);
// Must be a generic method with a ByRefFunc<,> parameter
Debug.Assert(propertyGetterByRefWrapperMethod != null);
Debug.Assert(propertyGetterByRefWrapperMethod.IsGenericMethodDefinition);
Debug.Assert(propertyGetterByRefWrapperMethod.GetParameters().Length == 2);
var getMethod = propertyInfo.GetMethod;
Debug.Assert(getMethod != null);
Debug.Assert(!getMethod.IsStatic);
Debug.Assert(getMethod.GetParameters().Length == 0);
// Instance methods in the CLR can be turned into static methods where the first parameter
// is open over "target". This parameter is always passed by reference, so we have a code
// path for value types and a code path for reference types.
if (getMethod.DeclaringType.GetTypeInfo().IsValueType)
{
// Create a delegate (ref TDeclaringType) -> TValue
return MakeFastPropertyGetter(
typeof(ByRefFunc<,>),
getMethod,
propertyGetterByRefWrapperMethod);
}
else
{
// Create a delegate TDeclaringType -> TValue
return MakeFastPropertyGetter(
typeof(Func<,>),
getMethod,
propertyGetterWrapperMethod);
}
}