Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
Expand Down Expand Up @@ -33,9 +34,41 @@ public static Getter CreateGetter(MemberInfo memberInfo)
{
if (memberInfo is PropertyInfo propInfo)
{
var createGetterGeneric = s_createGetterInternal.MakeGenericMethod(propInfo.DeclaringType!, propInfo.PropertyType).CreateDelegate<Func<PropertyInfo, Getter>>();
Getter accessor = createGetterGeneric(propInfo);
return accessor;
Type declaringType = propInfo.DeclaringType!;
Type propertyType = propInfo.PropertyType!;

if (declaringType.IsGenericType && declaringType.GetGenericTypeDefinition() == typeof(KeyValue<,>))
{
if (propInfo.Name == "Key")
{
return (obj) =>
{
return ((IKeyValue)obj).Key;
};
}
else
{
return (obj) =>
{
return ((IKeyValue)obj).Value;
};
}
}

// If either of the arguments to MakeGenericMethod is a valuetype, this is going to cause JITting.
// Only JIT if dynamic code is supported.
if (RuntimeFeature.IsDynamicCodeSupported || (!declaringType.IsValueType && !propertyType.IsValueType))
{
var createGetterGeneric = s_createGetterInternal.MakeGenericMethod(declaringType, propertyType).CreateDelegate<Func<PropertyInfo, Getter>>();
return createGetterGeneric(propInfo);
}
else
{
return (obj) =>
{
return propInfo.GetValue(obj);
};
}
}
else if (memberInfo is FieldInfo fieldInfo)
{
Expand All @@ -58,9 +91,41 @@ public static Setter CreateSetter(MemberInfo memberInfo)
PropertyInfo propInfo = (PropertyInfo)memberInfo;
if (propInfo.CanWrite)
{
var buildSetAccessorGeneric = s_createSetterInternal.MakeGenericMethod(propInfo.DeclaringType!, propInfo.PropertyType).CreateDelegate<Func<PropertyInfo, Setter>>();
Setter accessor = buildSetAccessorGeneric(propInfo);
return accessor;
Type declaringType = propInfo.DeclaringType!;
Type propertyType = propInfo.PropertyType!;

if (declaringType.IsGenericType && declaringType.GetGenericTypeDefinition() == typeof(KeyValue<,>))
{
if (propInfo.Name == "Key")
{
return (ref object obj, object? val) =>
{
((IKeyValue)obj).Key = val;
};
}
else
{
return (ref object obj, object? val) =>
{
((IKeyValue)obj).Value = val;
};
}
}

// If either of the arguments to MakeGenericMethod is a valuetype, this is going to cause JITting.
// Only JIT if dynamic code is supported.
if (RuntimeFeature.IsDynamicCodeSupported || (!declaringType.IsValueType && !propertyType.IsValueType))
{
var createSetterGeneric = s_createSetterInternal.MakeGenericMethod(propInfo.DeclaringType!, propInfo.PropertyType).CreateDelegate<Func<PropertyInfo, Setter>>();
return createSetterGeneric(propInfo);
}
else
{
return (ref object obj, object? val) =>
{
propInfo.SetValue(obj, val);
};
}
}
else
{
Expand Down Expand Up @@ -89,24 +154,6 @@ public static Setter CreateSetter(MemberInfo memberInfo)

private static Getter CreateGetterInternal<DeclaringType, PropertyType>(PropertyInfo propInfo)
{
if (typeof(DeclaringType).IsGenericType && typeof(DeclaringType).GetGenericTypeDefinition() == typeof(KeyValue<,>))
{
if (propInfo.Name == "Key")
{
return (obj) =>
{
return ((IKeyValue)obj).Key;
};
}
else
{
return (obj) =>
{
return ((IKeyValue)obj).Value;
};
}
}

if (typeof(DeclaringType).IsValueType)
{
var getMethod = propInfo.GetMethod!.CreateDelegate<StructGetDelegate<DeclaringType, PropertyType>>();
Expand All @@ -130,24 +177,6 @@ private static Getter CreateGetterInternal<DeclaringType, PropertyType>(Property

private static Setter CreateSetterInternal<DeclaringType, PropertyType>(PropertyInfo propInfo)
{
if (typeof(DeclaringType).IsGenericType && typeof(DeclaringType).GetGenericTypeDefinition() == typeof(KeyValue<,>))
{
if (propInfo.Name == "Key")
{
return (ref object obj, object? val) =>
{
((IKeyValue)obj).Key = val;
};
}
else
{
return (ref object obj, object? val) =>
{
((IKeyValue)obj).Value = val;
};
}
}

if (typeof(DeclaringType).IsValueType)
{
var setMethod = propInfo.SetMethod!.CreateDelegate<StructSetDelegate<DeclaringType, PropertyType>>();
Expand Down