Reputation: 1093
I need to change the Capacity
property of the dynamic variable of type List<*DynamicType*>
.
The problem is that Activator
returns object
-casted variable if variable type is not specified instead of proper List<*DynamicType*>
and the best I can do is to cast it to IList
:
DynamicTypeBuilder builder = new DynamicTypeBuilder() { ... };
Type dataType = builder.GenerateType(...);
Type listDataType = typeof(List<>).MakeGenericType(dataType);
IList list = (IList)Activator.CreateInstance(listDataType);
After some searching I found only one hack:
dynamic dynamicList = list;
dynamicList.Capacity = dataRowsCount;
Though this would be acceptable in my case I wonder if there is another way to do this.
Upvotes: 5
Views: 2285
Reputation: 1064144
Perhaps this is simpler:
object list = Activator.CreateInstance(listDataType,
new object[]{dataRowsCount});
Which should use the correct constructor?
Generics and reflection are indeed a pain in combination. The dynamic
hack here is no uglier than setting it via reflection (a magic string as a literal, vs an unverified property member), and dynamic
is internally optimised and cached (per-type), so I wouldn't have a problem with it. If you need to do more than just one property, you can also use dynamic
to flip into a generic method, to minimise the ugly:
void Evil<T>(List<T> list, int capacity) {
list.Capacity = capacity;
// do other stuff
}
...
dynamic list = Activator.CreateInstance(listDataType);
Evil(list, dataRowsCount);
Which will invoke the generic method with the correct T
. Not worth it just for 1 member, but it might be useful for more complex scenarios.
Upvotes: 3
Reputation: 1503669
You can do it with reflection:
var capacityProperty = listDataType.GetProperty("Capacity");
capacityProperty.SetValue(list, dataRowsCount, null);
An alternative is to write a generic method which does everything you want in a statically typed way, and call that with reflection instead. That can be a handy way of making sure you only need one piece of reflection.
Upvotes: 4