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.
A dynamic type variables are defined using the dynamic keyword. Example: dynamic Variable. dynamic MyDynamicVar = 1; The compiler compiles dynamic types into object types in most cases. However, the actual type of a dynamic type variable would be resolved at run-time.
The dynamic type is a static type, but an object of type dynamic bypasses static type checking. In most cases, it functions like it has type object . At compile time, an element that is typed as dynamic is assumed to support any operation.
The dynamic type is the real type of an object that might be accessed via a reference (pointer included) that point to a base type of its real type. class A { }; class B : public A { }; B l; A& k = l; Here k is a reference to an object of type A, but the real type of the referred object, its dynamic type, is B.
Dynamic types are similar to object types except that type checking for object type variables takes place at compile time, whereas that for the dynamic type variables takes place at runtime.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With