c# - 在 C# 中为 Xamarin 禁用泛型

标签 c# .net generics mono xamarin.ios

我有一个 C# 应用程序,它获取 ahead of time compiled使用 monotouch (Xamarin) 到 native iOS 代码

我链接的一些库使用泛型。然而,事实证明,这种编译方法会导致严重的代码膨胀,因为它使用了 C++ 风格的模板代码生成生成函数List<int>。 , List<string>等等

我想要的是 Java 风格的泛型,其中泛型用于编译时检查,但在运行时代码仅包含 List 的函数并且不适用于每种模板类型。

注意:这不是在 .Net CLR 中使用 C# 的问题,如 here 所述。出现此问题的原因是代码被 AOT 编译为 native 二进制文件而不是中间语言。此外,由于二进制文件是 native 的,因此对泛型方法的运行时类型检查相当无用。

问题:如何禁用泛型,即替换所有出现的 List<T>List ,在编译期间?这可能吗?

最佳答案

这是不可能的。

在 Java 上这是可能的,因为它们没有值类型,只有类(您可以通过自己不使用值类型来模拟此行为,仅使用 List<object> (或 object 子类),在这种情况下 AOT编译器只会生成一个 List 的实例)。

您说这不是 .NET CLR 的问题,这也不完全正确。 .NET CLR 和 Xamarin 的 AOT 编译器之间的区别在于,AOT 编译器不能等到执行时间才能确定是否需要特定实例化(因为 iOS 不允许在设备上生成可执行代码),它需要确保每个可能的实例化都可用。如果 .NET CLR 上的应用程序碰巧在运行时需要所有可能的通用实例化,那么您会遇到类似的问题(只是它会显示为运行时内存使用情况,而不是可执行文件大小,并且在桌面上通常不是问题无论如何)。

解决问题的受支持方法是为所有程序集启用托管链接器(在项目的 iOS 生成选项中,将“链接器行为”设置为“所有程序集”)。这将从您不使用的应用中删除所有托管代码,这在大多数情况下会显着减小应用大小。

您可以在此处找到有关托管链接器的更多信息:http://developer.xamarin.com/guides/ios/advanced_topics/linker/

如果您的应用程序仍然太大,请提交一个附加您的项目的错误 ( http://bugzilla.xamarin.com ),我们将查看是否可以以某种方式改进 AOT 编译器(例如,我们已经使用以下方法优化了值类型)大小相同,因此 List<int>List<uint> 仅生成一个实例)。

关于c# - 在 C# 中为 Xamarin 禁用泛型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31481844/

相关文章:

delphi - 如何检查某项是否支持通用接口(interface)?

c# - 使用字符串的值创建新的表单对象

c# - ASP.NET WebApi 未收到发布数据

c# - 订购 ICollection

c# - SSIS - 搜索字符串 - 脚本任务

C# 和匿名对象数组

c# - 接口(interface) "IRepository<T>"的正确文件名是什么

c# - 你能解释一下这种泛型行为吗?如果我有解决方法?

.net - 通过 SDK 与 Lync 2010 和 2013 集成

c# - 是否可以在已经创建的实例上直接调用构造函数?