summaryrefslogtreecommitdiff
path: root/src/mscorlib/src/System/DelegateSerializationHolder.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/mscorlib/src/System/DelegateSerializationHolder.cs')
-rw-r--r--src/mscorlib/src/System/DelegateSerializationHolder.cs48
1 files changed, 28 insertions, 20 deletions
diff --git a/src/mscorlib/src/System/DelegateSerializationHolder.cs b/src/mscorlib/src/System/DelegateSerializationHolder.cs
index 061f92d42e..d7ad827673 100644
--- a/src/mscorlib/src/System/DelegateSerializationHolder.cs
+++ b/src/mscorlib/src/System/DelegateSerializationHolder.cs
@@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-
+
using System;
using System.Reflection;
using System.Runtime.Remoting;
@@ -21,17 +21,17 @@ namespace System
{
// Used for MulticastDelegate
- if (method == null)
+ if (method == null)
throw new ArgumentNullException(nameof(method));
Contract.EndContractBlock();
-
+
Type c = delegateType.BaseType;
if (c == null || (c != typeof(Delegate) && c != typeof(MulticastDelegate)))
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeDelegate"),"type");
+ throw new ArgumentException(SR.Arg_MustBeDelegate, "type");
if (method.DeclaringType == null)
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_GlobalMethodSerialization"));
+ throw new NotSupportedException(SR.NotSupported_GlobalMethodSerialization);
DelegateEntry de = new DelegateEntry(delegateType.FullName, delegateType.Module.Assembly.FullName, target,
method.ReflectedType.Module.Assembly.FullName, method.ReflectedType.FullName, method.Name);
@@ -39,7 +39,7 @@ namespace System
if (info.MemberCount == 0)
{
info.SetType(typeof(DelegateSerializationHolder));
- info.AddValue("Delegate",de,typeof(DelegateEntry));
+ 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
@@ -108,15 +108,15 @@ namespace System
#region Private Data Members
private DelegateEntry m_delegateEntry;
private MethodInfo[] m_methods;
- #endregion
-
+ #endregion
+
#region Constructor
private DelegateSerializationHolder(SerializationInfo info, StreamingContext context)
{
if (info == null)
throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
-
+
bool bNewWire = true;
try
@@ -170,7 +170,7 @@ namespace System
private void ThrowInsufficientState(string field)
{
throw new SerializationException(
- Environment.GetResourceString("Serialization_InsufficientDeserializationState", field));
+ SR.Format(SR.Serialization_InsufficientDeserializationState, field));
}
private DelegateEntry OldDelegateWireFormat(SerializationInfo info, StreamingContext context)
@@ -206,26 +206,34 @@ namespace System
// We cannot use Type.GetType directly, because of AppCompat - assembly names starting with '[' would fail to load.
RuntimeType type = (RuntimeType)Assembly.GetType_Compat(de.assembly, de.type);
- RuntimeType targetType = (RuntimeType)Assembly.GetType_Compat(de.targetTypeAssembly, de.targetTypeName);
+
+ // {de.targetTypeAssembly, de.targetTypeName} do not actually refer to the type of the target, but the reflected
+ // type of the method. Those types may be the same when the method is on the target's type or on a type in its
+ // inheritance chain, but those types may not be the same when the method is an extension method for the
+ // target's type or a type in its inheritance chain.
// If we received the new style delegate encoding we already have the target MethodInfo in hand.
if (m_methods != null)
{
- if(de.target != null && !targetType.IsInstanceOfType(de.target))
- throw new InvalidCastException();
- Object target=de.target;
- d = Delegate.CreateDelegateNoSecurityCheck(type, target, m_methods[index]);
+ // The method info is serialized, so the target type info is redundant. The desktop framework does no
+ // additional verification on the target type info.
+ d = Delegate.CreateDelegateNoSecurityCheck(type, de.target, m_methods[index]);
}
else
{
if (de.target != null)
{
- if(!targetType.IsInstanceOfType(de.target))
- throw new InvalidCastException();
- d = Delegate.CreateDelegate(type, de.target, de.methodName);
+ // For consistency with the desktop framework, when the method info is not serialized for a closed
+ // delegate, the method is assumed to be on the target's type or in its inheritance chain. An extension
+ // method would not work on this path for the above reason and also because the delegate binds to
+ // instance methods only. The desktop framework does no additional verification on the target type info.
+ d = Delegate.CreateDelegate(type, de.target, de.methodName);
}
else
+ {
+ RuntimeType targetType = (RuntimeType)Assembly.GetType_Compat(de.targetTypeAssembly, de.targetTypeName);
d = Delegate.CreateDelegate(type, targetType, de.methodName);
+ }
}
}
catch (Exception e)
@@ -256,7 +264,7 @@ namespace System
else
{
object[] invocationList = new object[count];
-
+
for (DelegateEntry de = m_delegateEntry; de != null; de = de.Entry)
{
// Be careful to match the index we pass to GetDelegate (used to look up extra information for each delegate) to
@@ -272,7 +280,7 @@ namespace System
#region ISerializable
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_DelegateSerHolderSerial"));
+ throw new NotSupportedException(SR.NotSupported_DelegateSerHolderSerial);
}
#endregion
}