GIVEN:
If you have the values:
Type type
IEnumerable enumerable
And the following conditions are met:
typeof(IEnumerable).IsAssignableFrom(type)
enumerable.All(element => element.GetType() == type.GetElementType())
GENERAL QUESTION:
Is it possible to create an instance of type
via reflection that contains all of the elements of enumerable
?
BACKGROUND:
Most of the types in System.Collections
have a constructor like Example(ICollection)
, and if type
has a constructor like that it is simple and straightforward to do Activator.CreateInstance(type, enumerable)
. For types like Dictionary<TKey, TValue>
though, it is not that simple. The only solution I have thought of looks like this:
var dictionary = (IDictionary) Activator.CreateInstance(type);
var elementType = enumerable.First().GetType();
var key = elementType.GetProperty("Key");
var value = elementType.GetProperty("Value");
foreach (var element in enumerable)
{
dictionary.Add(key.GetValue(element), value.GetValue(element));
}
I would be more willing to accept this solution of KeyValuePair<TKey, TValue>
implemented an interface which contained the properties Key
and Value
so you could say:
var keyValuePair = (IKeyValuePair) element;
dictionary.Add(keyValuePair.Key, keyValuePair.Value);
rather than relying on reflection to get the aforementioned property values.
This solution would only work for types within System.Collections
or custom types that strongly adhere to the definitions of said types.
SPECIFIC QUESTION:
Is there a more elegant way of converting enumerable
to the type of type
that also could account for edge cases like MyCollection : ICollection
, where the type definition is not known to us?
UPDATE:
Here is an example:
var original = new Dictionary<int, string>
{
//values
};
var type = original.GetType();
var enumerable = original.AsEnumerable();
var copy = (Dictionary<int, string>) DoSomeMagic(type, enumerable);
object DoSomeMagic(Type type, IEnumerable enumerable)
{
//Add magic here
}
Aucun commentaire:
Enregistrer un commentaire