Question:
Is there a static way to reliably determine the type contained by a type derived from CollectionBase
, using Reflection or Microsoft.Cci?
Background:
I am working on a code generator that copies types, makes customized versions of those types, and converters between. It walks the types in the source assembly via Microsoft.Cci. It prints out source code using textual templates. It does a lot of conversion and customization, and tosses out code that I don't care about.
In my resulting code, I intend to replace List<T>
everywhere that a CollectionBase
, IEnumerable<T>
, or T[]
was previously used. I want to use List<T>
because I am pretty sure I can serialize it without extra work, which is important for my application. T
is concrete in every case. I am trying not to copy CollectionBase
classes because I'd have to copy over the custom implementation, and I'd like to avoid having to do that in my code generator.
The only part I'm having a problem with is determining T
for List<T>
when replacing a custom CollectionBase
.
What I've done so far:
I have briefly looked at the MSDN docs and samples for CollectionBase
, and they mention creating a custom Add
method on your derived type. I don't think this is in any way enforced, so I'm not sure I can rely on that. An implementor could name it something else, or worse, have a collection that supports multiple types, with Object
as their only common ancestor.
Alternatives I have considered:
Maybe the default serialization does some tricks that I can take advantage of. Is there a default serialization for CollectionBase
collections, or do you generally have to implement it yourself? If you have to do it yourself, is there some reliable metadata I could look at in order to determine the types? If it supports default serialization, does it rely on the runtime types of the items in the collection?
I could make a mapping in my code generator of known CollectionBase
types, mapped to their corresponding T
for List<T>
. If a given CollectionBase
type that I encounter isn't in the list, throw an exception. This is probably what I'll go with if I there isn't a reliable alternative.
I'm still not sure enough about what you want to do to give advice. Still, do your CollectionBase-derived classes all implement Add(T)? If so, you could look for an Add method with single parameter of type other than object, and use that type for T.