Skip to content

Instantly share code, notes, and snippets.

@darrenkopp
Created March 30, 2010 15:21
Show Gist options
  • Save darrenkopp/349189 to your computer and use it in GitHub Desktop.
Save darrenkopp/349189 to your computer and use it in GitHub Desktop.
private object ReadList(Type listType, object existingContainer)
{
if (IsDictionary(listType))
{
return ReadDictionary(listType, existingContainer);
}
NewDocument(_reader.ReadInt32());
var isReadonly = false;
var itemType = ListHelper.GetListItemType(listType);
var container = existingContainer == null ? ListHelper.CreateContainer(listType, itemType, out isReadonly) : (IList)existingContainer;
try
{
var fill = typeof(BsonDeserializer)
.GetMethod("Fill").MakeGenericMethod(itemType)
.Invoke(this, new object[] { existingContainer });
}
catch (TargetInvocationException ex)
{
throw ex.InnerException;
}
if (listType.IsArray)
{
return ListHelper.ToArray((List<object>)container, itemType);
}
if (isReadonly)
{
return listType.GetConstructor(BindingFlags.Instance | BindingFlags.Public, null, new[] { container.GetType() }, null).Invoke(new object[] { container });
}
return container;
}
private void Fill<T>(ICollection<T> collection)
{
var itemType = typeof(T);
while (!IsDone())
{
var storageType = ReadType();
ReadName();
if (storageType == BSONTypes.Object)
{
NewDocument(_reader.ReadInt32());
}
var value = DeserializeValue(itemType, storageType);
collection.Add((T)value);
}
}
// make something similar to Action<object> action = instance => collection.Add((T)instance)
var collectionType = typeof(ICollection<>).MakeGenericType(listType);
var collection = Expression.Constant(existingContainer, collectionType);
var instanceParameter = Expression.Parameter(typeof(object), "instance");
var filler = Expression.Lambda<Action<object>>(
// collection.Add((T)instance)
Expression.Call(
collection,
collectionType.GetMethod("Add"),
Expression.Convert(instanceParameter, listType)
),
instanceParameter
).Compile();
while (!IsDone())
{
var storageType = ReadType();
ReadName();
if (storageType == BSONTypes.Object)
{
NewDocument(_reader.ReadInt32());
}
var value = DeserializeValue(itemType, storageType);
filler(value);
//container.Add(value);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment