You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET MAUI如何获取内部类TabbedPageManager的私有BottomNavigationView属性?

.NET MAUI中解决TabbedPage内部类私有属性访问的AOT警告问题

问题背景

在.NET MAUI应用中自定义TabbedPage行为时,通过反射访问内部类TabbedPageManager的私有属性BottomNavigationView触发了IL2075警告。原实现代码如下:

Microsoft.Maui.Handlers.TabbedViewHandler.Mapper.AppendToMapping("TabbedPageCenterLabels", (handler, view) => {
    var tabbedPageManager = typeof(TabbedPage).GetField("_tabbedPageManager", BindingFlags.NonPublic | BindingFlags.Instance)?.
        GetValue(handler.VirtualView);

    var navView = (BottomNavigationView?)tabbedPageManager.GetType()
        .GetProperty("BottomNavigationView", BindingFlags.NonPublic | BindingFlags.Instance)
        ?.GetValue(tabbedPageManager);
});

由于TabbedPageManager是内部类,无法直接通过typeof(TabbedPageManager)获取类型;尝试使用UnsafeAccessor时,因参数类型不可访问而失败:

[UnsafeAccessor(UnsafeAccessorKind.Method, Name = "get_BottomNavigationView")]
extern static BottomNavigationView InstanceGetter(TabbedPageManager @this);

解决方案

方案1:用UnsafeAccessor针对object类型访问私有属性

将UnsafeAccessor的参数类型改为object(规避内部类不可访问的限制),直接指定属性的Getter操作:

// 定义访问BottomNavigationView属性的Unsafe访问器
[UnsafeAccessor(UnsafeAccessorKind.PropertyGet, Name = "BottomNavigationView")]
extern static BottomNavigationView? GetBottomNavigationView(object tabbedPageManager);

// 在映射逻辑中使用
Microsoft.Maui.Handlers.TabbedViewHandler.Mapper.AppendToMapping("TabbedPageCenterLabels", (handler, view) => {
    // 获取_tabbedPageManager私有字段
    var tabbedPageManagerField = typeof(TabbedPage).GetField("_tabbedPageManager", BindingFlags.NonPublic | BindingFlags.Instance);
    if (tabbedPageManagerField == null) return;

    var tabbedPageManager = tabbedPageManagerField.GetValue(handler.VirtualView);
    if (tabbedPageManager == null) return;

    // 通过UnsafeAccessor获取目标属性
    var navView = GetBottomNavigationView(tabbedPageManager);
    // 后续对navView的自定义逻辑...
});

方案2:全流程用UnsafeAccessor替代反射(彻底消除IL2075)

同时为_tabbedPageManager字段和BottomNavigationView属性定义UnsafeAccessor,完全避免反射操作:

// 访问TabbedPage的_tabbedPageManager私有字段
[UnsafeAccessor(UnsafeAccessorKind.Field, Name = "_tabbedPageManager")]
extern static object? GetTabbedPageManager(TabbedPage tabbedPage);

// 访问TabbedPageManager的BottomNavigationView私有属性
[UnsafeAccessor(UnsafeAccessorKind.PropertyGet, Name = "BottomNavigationView")]
extern static BottomNavigationView? GetBottomNavigationView(object tabbedPageManager);

// 在映射逻辑中使用
Microsoft.Maui.Handlers.TabbedViewHandler.Mapper.AppendToMapping("TabbedPageCenterLabels", (handler, view) => {
    if (handler.VirtualView is not TabbedPage tabbedPage) return;

    var tabbedPageManager = GetTabbedPageManager(tabbedPage);
    if (tabbedPageManager == null) return;

    var navView = GetBottomNavigationView(tabbedPageManager);
    // 后续对navView的自定义逻辑...
});

注意事项

  • UnsafeAccessor需要.NET 7及以上版本支持,且需在项目csproj文件中启用不安全代码:<AllowUnsafeBlocks>true</AllowUnsafeBlocks>。
  • 该方式依赖.NET MAUI内部实现细节,版本更新可能导致内部结构变化,需做好兼容性测试。
  • 相比反射,UnsafeAccessor在AOT编译下无警告,且性能更优。

内容的提问来源于stack exchange,提问作者Saftpresse99

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 07:19:58