Reputation: 8007
I'd like to recover type information using reflection. I have
public Foo(object coll, string tValue)
{
var x = col1 as IList;
if (x != null)
x.Action();
var y = col1 as IDictionary;
if (y != null)
y.Action();
}
But would like to have
public Foo(object coll, string tValue)
{
var x = col1 as IList<TValue>;
if (x != null)
x.Action();
var y = col1 as IDictionary<int, TValue>;
if (y != null)
y.Action();
}
Is it possible to arrive at and use generic interfaces instead of the old-school non-generic collection interfaces, given only the contained class name?
Once the local variable type is established, I'd like to avoid paying the reflection and dynamic invocation penalties when looping over the collection.
Another example, maybe clearer:
var list = new Dictionary<int, MyObject>();
list.Add(100, new MyObject());
object listObject = list;
var x = listObject as IDictionary<int, dynamic>;
if (x != null)
{
foreach (var entry in x)
{
Console.WriteLine(entry.Key);
Console.WriteLine(entry.Value);
}
}
x is null...
Upvotes: 0
Views: 122
Reputation: 2999
I'm not sure if you intend to call a method on generic collection for every item in the collection or if you just want the values from the generic collection.
For your third block of code, you could continue to use the non-generic interface and use an enumerator.
var x = listObject as IDictionary;
if (x != null)
{
var en = x.GetEnumerator();
while(en.MoveNext())
{
Console.WriteLine(en.Key);
Console.WriteLine(en.Value);
}
}
If you intend to call a method without knowing the exact generic types for the generic IList or IDictionary, then you'll have to use MethodInfo.Invoke. Cache the MethodInfo outside of the loop for a small performance boost. CreateDelegate would be faster, but you'll need to know the exact generic types. You could get around that with expression trees, but the amount of code to maintain might not be worth the performance gain. Check out MagicMethod in Jon Skeets article Making reflection fly and exploring delegates
Upvotes: 2