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

如何访问外部程序集内部类EntityNetPlayer的List私有字段及创建该类List字段?

这两个问题其实都绕不开.NET中internal类型的访问限制,我来一步步给你拆解解决办法:

问题1:泛型参数T为内部类时,如何访问List?

你已经通过反射拿到了List<T>的实例(就是GetAlivePlayers方法返回的对象),但因为T是外部程序集的internal类,没法直接在代码里写List<EntityNetPlayer>强转,这里有两种实用方案:

  • 方案1:用dynamic简化操作
    把获取到的对象转成dynamic类型,就能直接调用List的方法、遍历元素,甚至访问内部类的属性/字段(前提是你知道它们的名称):

    object alivePlayersObj = GetAlivePlayers(yourInstance);
    dynamic alivePlayers = alivePlayersObj;
    
    // 遍历所有玩家
    foreach (dynamic player in alivePlayers)
    {
        // 假设EntityNetPlayer有IsAlive属性,直接访问
        bool isPlayerAlive = player.IsAlive;
        // 也可以结合反射操作内部字段
        object internalFieldValue = player.GetType()
            .GetField("SomeInternalField", BindingFlags.Instance | BindingFlags.NonPublic)
            .GetValue(player);
    }
    

    这种方式代码简洁,但没有编译时校验,拼写错误只会在运行时暴露。

  • 方案2:全程用反射操作List
    如果你不想依赖dynamic,完全可以用反射调用List的属性和方法:

    object alivePlayersObj = GetAlivePlayers(yourInstance);
    Type listType = alivePlayersObj.GetType();
    
    // 获取List的元素数量
    int playerCount = (int)listType.GetProperty("Count").GetValue(alivePlayersObj);
    
    // 通过索引器遍历所有元素
    PropertyInfo indexerProp = listType.GetProperty("Item", new[] { typeof(int) });
    for (int i = 0; i < playerCount; i++)
    {
        object player = indexerProp.GetValue(alivePlayersObj, new object[] { i });
        // 对player进行反射操作,比如获取公开属性
        string playerName = (string)player.GetType().GetProperty("PlayerName").GetValue(player);
    }
    

问题2:如何创建外部程序集internal类(EntityNetPlayer)的List字段?

要创建List<EntityNetPlayer>类型的实例,核心是先拿到EntityNetPlayer的Type,再动态构建泛型List类型:

  1. 获取EntityNetPlayer的Type
    因为这个类和你传入GetAlivePlayers的instance对象属于同一个外部程序集,你可以从实例的程序集里获取它的Type(注意要写全类的命名空间):

    // 从instance所在程序集获取EntityNetPlayer的Type
    Type entityNetPlayerType = instance.GetType().Assembly.GetType("YourFullNamespace.EntityNetPlayer");
    

    如果你知道外部程序集的名称,也可以直接加载程序集获取:

    Assembly externalAssembly = Assembly.Load("ExternalAssemblyName");
    Type entityNetPlayerType = externalAssembly.GetType("YourFullNamespace.EntityNetPlayer");
    
  2. 构建并实例化List
    拿到Type后,用typeof(List<>)结合MakeGenericType创建泛型List类型,再通过Activator.CreateInstance实例化:

    // 创建List<EntityNetPlayer>的类型
    Type listType = typeof(List<>).MakeGenericType(entityNetPlayerType);
    // 实例化一个空的List
    object newAlivePlayersList = Activator.CreateInstance(listType);
    
  3. (可选)给原字段赋值
    如果要替换原来的AlivePlayers字段,直接用反射的SetValue方法:

    instance.GetType()
            .GetField("AlivePlayers", BindingFlags.Instance | BindingFlags.NonPublic)
            .SetValue(instance, newAlivePlayersList);
    

小提示

如果外部程序集没有给你的程序集添加InternalsVisibleToAttribute,你永远没法在代码里直接引用EntityNetPlayer类型,只能全程靠反射或dynamic间接操作——这是.NET访问权限机制的硬性限制。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 03:51:44