private bool WriteSpecialObject(object o, bool checkForCollections)
{
// if the object here is value type, it is in fact boxed
// value type - the reference layout is fine, we should
// write it using WriteField
var type = o.GetType();
if(type.IsValueType)
{
WriteField(type, o);
return true;
}
var mDelegate = o as MulticastDelegate;
if(mDelegate != null)
{
// if the target is trasient, we omit associated delegate entry
var invocationList = GetDelegatesWithNonTransientTargets(mDelegate);
writer.Write(invocationList.Length);
foreach(var del in invocationList)
{
WriteField(typeof(object), del.Target);
Methods.TouchAndWriteId(new MethodDescriptor(del.Method));
}
return true;
}
if(type.IsArray)
{
var elementType = type.GetElementType();
var array = o as Array;
WriteArray(elementType, array);
return true;
}
if(checkForCollections)
{
CollectionMetaToken collectionToken;
if (CollectionMetaToken.TryGetCollectionMetaToken(o.GetType(), out collectionToken))
{
// here we can have normal or extension method that needs to be treated differently
int count = collectionToken.CountMethod.IsStatic ?
(int)collectionToken.CountMethod.Invoke(null, new[] { o }) :
(int)collectionToken.CountMethod.Invoke(o, null);
WriteEnumerable(collectionToken.FormalElementType, count, (IEnumerable)o);
return true;
}
}
return false;
}