我需要更改Capacity
类型的动态变量的List<*DynamicType*>
属性。
问题是Activator
返回object
- 如果未指定变量类型而不是正确的List<*DynamicType*>
,则转换变量,我能做的最好的事情是将其强制转换为IList
:< / p>
DynamicTypeBuilder builder = new DynamicTypeBuilder() { ... };
Type dataType = builder.GenerateType(...);
Type listDataType = typeof(List<>).MakeGenericType(dataType);
IList list = (IList)Activator.CreateInstance(listDataType);
经过一番搜索,我发现只有一个黑客:
dynamic dynamicList = list;
dynamicList.Capacity = dataRowsCount;
虽然在我的情况下这是可以接受的,但我想知道是否还有另一种方法可以做到这一点。
答案 0 :(得分:4)
你可以用反射来做到这一点:
var capacityProperty = listDataType.GetProperty("Capacity");
capacityProperty.SetValue(list, dataRowsCount, null);
另一种方法是编写一个通用方法,以静态类型的方式执行所需的所有操作,然后使用反射调用 。这可以是确保您只需要一次反射的便捷方式。
答案 1 :(得分:3)
也许这更简单:
object list = Activator.CreateInstance(listDataType,
new object[]{dataRowsCount});
哪个应该使用正确的构造函数?
泛型和反思确实是一种痛苦的组合。这里的dynamic
hack并不比通过反射(魔术字符串作为文字,与未经验证的属性成员)设置一样丑陋,dynamic
内部优化和缓存(每种类型),所以我不会有问题。如果您需要做的不仅仅是一个属性,您还可以使用dynamic
翻转一般的方法,以最大限度地减少丑陋:
void Evil<T>(List<T> list, int capacity) {
list.Capacity = capacity;
// do other stuff
}
...
dynamic list = Activator.CreateInstance(listDataType);
Evil(list, dataRowsCount);
将使用正确的T
调用泛型方法。仅仅对于1个成员来说不值得,但它可能对更复杂的场景有用。