转换为动态类型变量的通用列表

发布于 2024-12-10 11:44:01 字数 659 浏览 0 评论 0原文

我需要更改 List<*DynamicType*> 类型的动态变量的 Capacity 属性。 问题是,如果未指定变量类型,Activator 将返回 object 转换的变量,而不是正确的 List<*DynamicType*> 和最佳值我能做的就是将其转换为IList

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;

虽然这在我的情况下是可以接受的,但我想知道是否还有另一种方法可以做到这一点。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

最美的太阳 2024-12-17 11:44:01

您可以使用反射来完成此操作:

var capacityProperty = listDataType.GetProperty("Capacity");
capacityProperty.SetValue(list, dataRowsCount, null);

另一种方法是编写一个通用方法,以静态类型的方式执行您想要的所有操作,然后使用反射来调用那个。这是确保您只需要一个反射的便捷方法。

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.

泪眸﹌ 2024-12-17 11:44:01

也许这更简单:

object list = Activator.CreateInstance(listDataType,
    new object[]{dataRowsCount});

哪个应该使用正确的构造函数?

泛型和反射结合起来确实很痛苦。这里的 dynamic 黑客并不比通过反射设置它更难看(作为文字的魔术字符串,与未经验证的属性成员),并且 dynamic 是内部优化和缓存的(每个-type),所以我不会有任何问题。如果您需要执行多个属性,您还可以使用 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 名成员而言不值得,但对于更复杂的场景可能有用。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文