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 @@ -635,24 +635,44 @@ private static ReflectionXmlSerializationReaderHelper.SetMemberValueDelegate Get
{
MemberInfo memberInfo = ReflectionXmlSerializationHelper.GetEffectiveSetInfo(o.GetType(), memberName);
Debug.Assert(memberInfo != null, "memberInfo could not be retrieved");
Type memberType;
if (memberInfo is PropertyInfo propInfo)
{
memberType = propInfo.PropertyType;
}
else if (memberInfo is FieldInfo fieldInfo)

if (type.IsValueType || !RuntimeFeature.IsDynamicCodeSupported)
{
memberType = fieldInfo.FieldType;
if (memberInfo is PropertyInfo propInfo)
{
result = new ReflectionXmlSerializationReaderHelper.SetMemberValueDelegate(propInfo.SetValue);
}
else if (memberInfo is FieldInfo fieldInfo)
{
result = new ReflectionXmlSerializationReaderHelper.SetMemberValueDelegate(fieldInfo.SetValue);
}
else
{
throw new InvalidOperationException(SR.XmlInternalError);
}
}
else
{
throw new InvalidOperationException(SR.XmlInternalError);
Type memberType;
if (memberInfo is PropertyInfo propInfo)
{
memberType = propInfo.PropertyType;
}
else if (memberInfo is FieldInfo fieldInfo)
{
memberType = fieldInfo.FieldType;
}
else
{
throw new InvalidOperationException(SR.XmlInternalError);
}

MethodInfo getSetMemberValueDelegateWithTypeGenericMi = typeof(ReflectionXmlSerializationReaderHelper).GetMethod("GetSetMemberValueDelegateWithType", BindingFlags.Static | BindingFlags.Public)!;
MethodInfo getSetMemberValueDelegateWithTypeMi = getSetMemberValueDelegateWithTypeGenericMi.MakeGenericMethod(o.GetType(), memberType);
var getSetMemberValueDelegateWithType = getSetMemberValueDelegateWithTypeMi.CreateDelegate<Func<MemberInfo, ReflectionXmlSerializationReaderHelper.SetMemberValueDelegate>>();
result = getSetMemberValueDelegateWithType(memberInfo);
}

MethodInfo getSetMemberValueDelegateWithTypeGenericMi = typeof(ReflectionXmlSerializationReaderHelper).GetMethod("GetSetMemberValueDelegateWithType", BindingFlags.Static | BindingFlags.Public)!;
MethodInfo getSetMemberValueDelegateWithTypeMi = getSetMemberValueDelegateWithTypeGenericMi.MakeGenericMethod(o.GetType(), memberType);
var getSetMemberValueDelegateWithType = getSetMemberValueDelegateWithTypeMi.CreateDelegate<Func<MemberInfo, ReflectionXmlSerializationReaderHelper.SetMemberValueDelegate>>();
result = getSetMemberValueDelegateWithType(memberInfo);
delegateCacheForType[memberName] = result;
}
}
Expand Down Expand Up @@ -2097,46 +2117,31 @@ internal static class ReflectionXmlSerializationReaderHelper

public static SetMemberValueDelegate GetSetMemberValueDelegateWithType<TObj, TParam>(MemberInfo memberInfo)
{
if (typeof(TObj).IsValueType)
Debug.Assert(!typeof(TObj).IsValueType);
Action<TObj, TParam>? setTypedDelegate = null;
if (memberInfo is PropertyInfo propInfo)
{
if (memberInfo is PropertyInfo propInfo)
var setMethod = propInfo.GetSetMethod(true);
if (setMethod == null)
{
return propInfo.SetValue;
}
else if (memberInfo is FieldInfo fieldInfo)
{
return fieldInfo.SetValue;
}

throw new InvalidOperationException(SR.XmlInternalError);
setTypedDelegate = setMethod.CreateDelegate<Action<TObj, TParam>>();
}
else
else if (memberInfo is FieldInfo fieldInfo)
{
Action<TObj, TParam>? setTypedDelegate = null;
if (memberInfo is PropertyInfo propInfo)
{
var setMethod = propInfo.GetSetMethod(true);
if (setMethod == null)
{
return propInfo.SetValue;
}

setTypedDelegate = setMethod.CreateDelegate<Action<TObj, TParam>>();
}
else if (memberInfo is FieldInfo fieldInfo)
{
var objectParam = Expression.Parameter(typeof(TObj));
var valueParam = Expression.Parameter(typeof(TParam));
var fieldExpr = Expression.Field(objectParam, fieldInfo);
var assignExpr = Expression.Assign(fieldExpr, valueParam);
setTypedDelegate = Expression.Lambda<Action<TObj, TParam>>(assignExpr, objectParam, valueParam).Compile();
}

return delegate (object? o, object? p)
{
setTypedDelegate!((TObj)o!, (TParam)p!);
};
var objectParam = Expression.Parameter(typeof(TObj));
var valueParam = Expression.Parameter(typeof(TParam));
var fieldExpr = Expression.Field(objectParam, fieldInfo);
var assignExpr = Expression.Assign(fieldExpr, valueParam);
setTypedDelegate = Expression.Lambda<Action<TObj, TParam>>(assignExpr, objectParam, valueParam).Compile();
}

return delegate (object? o, object? p)
{
setTypedDelegate!((TObj)o!, (TParam)p!);
};
}
}
}