internal static DelegateEntry GetDelegateSerializationInfo(
SerializationInfo info, Type delegateType, Object target, MethodInfo method, int targetIndex)
{
// Used for MulticastDelegate
if (method == null)
throw new ArgumentNullException("method");
if (!method.IsPublic || (method.DeclaringType != null && !method.DeclaringType.IsVisible))
new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).Demand();
Type c = delegateType.BaseType;
if (c == null || (c != typeof(Delegate) && c != typeof(MulticastDelegate)))
throw new ArgumentException(Environment.GetResourceString("Arg_MustBeDelegate"),"type");
if (method.DeclaringType == null)
throw new NotSupportedException(Environment.GetResourceString("NotSupported_GlobalMethodSerialization"));
DelegateEntry de = new DelegateEntry(delegateType.FullName, delegateType.Module.Assembly.FullName, target,
method.ReflectedType.Module.Assembly.FullName, method.ReflectedType.FullName, method.Name);
if (info.MemberCount == 0)
{
info.SetType(typeof(DelegateSerializationHolder));
info.AddValue("Delegate",de,typeof(DelegateEntry));
}
// target can be an object so it needs to be added to the info, or else a fixup is needed
// when deserializing, and the fixup will occur too late. If it is added directly to the
// info then the rules of deserialization will guarantee that it will be available when
// needed
if (target != null)
{
String targetName = "target" + targetIndex;
info.AddValue(targetName, de.target);
de.target = targetName;
}
// Due to a number of additions (delegate signature binding relaxation, delegates with open this or closed over the
// first parameter and delegates over generic methods) we need to send a deal more information than previously. We can
// get this by serializing the target MethodInfo. We still need to send the same information as before though (the
// DelegateEntry above) for backwards compatibility. And we want to send the MethodInfo (which is serialized via an
// ISerializable holder) as a top-level child of the info for the same reason as the target above -- we wouldn't have an
// order of deserialization guarantee otherwise.
String methodInfoName = "method" + targetIndex;
info.AddValue(methodInfoName, method);
return de;
}
#endregion