Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / clr / src / BCL / System / MulticastDelegate.cs / 1407647 / MulticastDelegate.cs
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
namespace System
{
using System;
using System.Reflection;
using System.Runtime;
using System.Runtime.Serialization;
using System.Diagnostics.Contracts;
using System.Reflection.Emit;
[Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
public abstract class MulticastDelegate : Delegate
{
// This is set under 3 circumstances
// 1. Multicast delegate
// 2. Secure delegate
// 3. Inner delegate of secure delegate where the secure delegate security context is a collectible method
private Object _invocationList;
private IntPtr _invocationCount;
// This constructor is called from the class generated by the
// compiler generated code (This must match the constructor
// in Delegate
protected MulticastDelegate(Object target, String method) : base(target, method)
{
}
// This constructor is called from a class to generate a
// delegate based upon a static method name and the Type object
// for the class defining the method.
protected MulticastDelegate(Type target, String method) : base(target, method)
{
}
internal bool IsUnmanagedFunctionPtr()
{
return (_invocationCount == (IntPtr)(-1));
}
internal bool InvocationListLogicallyNull()
{
return (_invocationList == null) || (_invocationList is LoaderAllocator) || (_invocationList is DynamicResolver);
}
[System.Security.SecurityCritical]
public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
int targetIndex = 0;
Object[] invocationList = _invocationList as Object[];
if (invocationList == null)
{
MethodInfo method = Method;
// A MethodInfo object can be a RuntimeMethodInfo, a RefEmit method (MethodBuilder, etc), or a DynamicMethod
// One can only create delegates on RuntimeMethodInfo and DynamicMethod.
// If it is not a RuntimeMethodInfo (must be a DynamicMethod) or if it is an unmanaged function pointer, throw
if ( !(method is RuntimeMethodInfo) || IsUnmanagedFunctionPtr() )
throw new SerializationException(Environment.GetResourceString("Serialization_InvalidDelegateType"));
// We can't deal with secure delegates either.
if (!InvocationListLogicallyNull() && !_invocationCount.IsNull())
throw new SerializationException(Environment.GetResourceString("Serialization_InvalidDelegateType"));
DelegateSerializationHolder.GetDelegateSerializationInfo(info, this.GetType(), Target, method, targetIndex);
}
else
{
DelegateSerializationHolder.DelegateEntry nextDe = null;
int invocationCount = (int)_invocationCount;
for (int i = invocationCount; --i >= 0; )
{
MulticastDelegate d = (MulticastDelegate)invocationList[i];
MethodInfo method = d.Method;
// If it is not a RuntimeMethodInfo (must be a DynamicMethod) or if it is an unmanaged function pointer, skip
if ( !(method is RuntimeMethodInfo) || IsUnmanagedFunctionPtr() )
continue;
// We can't deal with secure delegates either.
if (!d.InvocationListLogicallyNull() && !d._invocationCount.IsNull())
continue;
DelegateSerializationHolder.DelegateEntry de = DelegateSerializationHolder.GetDelegateSerializationInfo(info, d.GetType(), d.Target, method, targetIndex++);
if (nextDe != null)
nextDe.Entry = de;
nextDe = de;
}
// if nothing was serialized it is a delegate over a DynamicMethod, so just throw
if (nextDe == null)
throw new SerializationException(Environment.GetResourceString("Serialization_InvalidDelegateType"));
}
}
// equals returns true IIF the delegate is not null and has the
// same target, method and invocation list as this object
[System.Security.SecuritySafeCritical] // auto-generated
public override sealed bool Equals(Object obj)
{
if (obj == null || !InternalEqualTypes(this, obj))
return false;
MulticastDelegate d = obj as MulticastDelegate;
if (d == null)
return false;
if (_invocationCount != (IntPtr)0)
{
// there are 4 kind of delegate kinds that fall into this bucket
// 1- Multicast (_invocationList is Object[])
// 2- Secure (_invocationList is Delegate)
// 3- Unmanaged FntPtr (_invocationList == null)
// 4- Open virtual (_invocationCount == MethodDesc of target, _invocationList == null, LoaderAllocator, or DynamicResolver)
if (InvocationListLogicallyNull())
{
if (IsUnmanagedFunctionPtr())
{
if (!d.IsUnmanagedFunctionPtr())
return false;
return CompareUnmanagedFunctionPtrs(this, d);
}
return base.Equals(obj);
}
else
{
if ((_invocationList as Delegate) != null)
{
// this is a secure delegate so we need to unwrap and check the inner one
return _invocationList.Equals(obj);
}
else
{
Contract.Assert((_invocationList as Object[]) != null, "empty invocation list on multicast delegate");
return InvocationListEquals(d);
}
}
}
else
{
// among the several kind of delegates falling into this bucket one has got a non
// empty _invocationList (open static with special sig)
// to be equals we need to check that _invocationList matches (both null is fine)
// and call the base.Equals()
if (!InvocationListLogicallyNull())
{
if (!_invocationList.Equals(d._invocationList))
return false;
return base.Equals(d);
}
// now we know 'this' is not a special one, so we can work out what the other is
if ((d._invocationCount != (IntPtr)0) || !InvocationListLogicallyNull())
{
if ((d._invocationList as Delegate) != null)
// this is a secure delegate so we need to unwrap and check the inner one
return (d._invocationList as Delegate).Equals(this);
}
// now we can call on the base
return base.Equals(d);
}
}
// Recursive function which will check for equality of the invocation list.
private bool InvocationListEquals(MulticastDelegate d)
{
Contract.Assert(d != null && (_invocationList as Object[]) != null, "bogus delegate in multicast list comparison");
Object[] invocationList = _invocationList as Object[];
if (d._invocationCount != _invocationCount)
return false;
int invocationCount = (int)_invocationCount;
for (int i = 0; i < invocationCount; i++)
{
Delegate dd = (Delegate)invocationList[i];
Object[] dInvocationList = d._invocationList as Object[];
if (!dd.Equals(dInvocationList[i]))
return false;
}
return true;
}
private bool TrySetSlot(Object[] a, int index, Object o)
{
if (a[index] == null && System.Threading.Interlocked.CompareExchange
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- EdmItemError.cs
- ListViewItem.cs
- AuthenticationModuleElement.cs
- Or.cs
- TraversalRequest.cs
- Perspective.cs
- StateFinalizationDesigner.cs
- Quaternion.cs
- ImageIndexConverter.cs
- LicenseContext.cs
- SimpleTypeResolver.cs
- ImageInfo.cs
- CodeTypeDeclarationCollection.cs
- StylusButton.cs
- SqlConnectionString.cs
- DataReaderContainer.cs
- ConvertBinder.cs
- FormViewInsertedEventArgs.cs
- XmlSchemaImport.cs
- MultipleViewProviderWrapper.cs
- BaseParagraph.cs
- XPathExpr.cs
- SoapCodeExporter.cs
- DataGridItem.cs
- ColorKeyFrameCollection.cs
- AdjustableArrowCap.cs
- ExceptionHandlersDesigner.cs
- FontFamily.cs
- DetailsViewInsertedEventArgs.cs
- ResourcePart.cs
- LineUtil.cs
- PersianCalendar.cs
- CodeDOMUtility.cs
- sqlnorm.cs
- ActivityDelegate.cs
- ZipIOLocalFileBlock.cs
- WindowsStreamSecurityBindingElement.cs
- StrokeCollection.cs
- Object.cs
- HostSecurityManager.cs
- HttpListenerException.cs
- ModelPerspective.cs
- OneToOneMappingSerializer.cs
- Vector3DAnimationBase.cs
- OptionUsage.cs
- XpsSerializerWriter.cs
- X509CertificateChain.cs
- GCHandleCookieTable.cs
- KeyFrames.cs
- CorrelationService.cs
- mansign.cs
- ConfigurationElementCollection.cs
- ConversionContext.cs
- HtmlInputText.cs
- Property.cs
- XmlSerializerSection.cs
- iisPickupDirectory.cs
- ErrorWebPart.cs
- XmlChildEnumerator.cs
- RunWorkerCompletedEventArgs.cs
- Compress.cs
- HandleExceptionArgs.cs
- Expander.cs
- UnitySerializationHolder.cs
- RelationshipConstraintValidator.cs
- DocumentPaginator.cs
- BitmapMetadata.cs
- DocumentsTrace.cs
- HtmlTableCellCollection.cs
- XmlQualifiedName.cs
- CodeAttributeDeclaration.cs
- WmpBitmapDecoder.cs
- SymDocumentType.cs
- CodeAttributeDeclarationCollection.cs
- PointAnimationUsingPath.cs
- BindingObserver.cs
- SimpleTypeResolver.cs
- SizeAnimation.cs
- SQLMoneyStorage.cs
- IxmlLineInfo.cs
- DrawToolTipEventArgs.cs
- MatrixTransform3D.cs
- ProofTokenCryptoHandle.cs
- CriticalHandle.cs
- RootBrowserWindow.cs
- CodeExpressionStatement.cs
- RegexMatchCollection.cs
- WaitForChangedResult.cs
- CompositeKey.cs
- FontStyles.cs
- ImageMetadata.cs
- CroppedBitmap.cs
- ConditionalBranch.cs
- WmlLinkAdapter.cs
- ExpressionContext.cs
- CheckPair.cs
- MimeMultiPart.cs
- Soap12ProtocolImporter.cs
- ExpiredSecurityTokenException.cs
- AsyncResult.cs