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

如何获取类实例中指定类型的所有成员并通过属性返回?

嘿,这就来帮你搞定这两个C#相关的问题!

问题1:如何获取类实例中指定类型的所有成员?

要实现这个需求,最常用的方式是反射——它能让我们在运行时检查类型的成员并获取对应的值。这里要注意区分「字段(Field)」和「属性(Property)」,因为你的示例里既有公共字段(A、B这些)又有属性(AllMyFloats),下面分别给出两种场景的实现:

  • 获取指定类型的字段值:

    using System;
    using System.Linq;
    using System.Reflection;
    using System.Collections.Generic;
    
    public static class MemberHelper
    {
        public static IEnumerable<object> GetTypedFieldValues<T>(object instance)
        {
            if (instance == null) throw new ArgumentNullException(nameof(instance));
            
            Type type = instance.GetType();
            // 获取所有公共实例字段,筛选类型为T的
            FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.Instance)
                                     .Where(f => f.FieldType == typeof(T))
                                     .ToArray();
            
            foreach (FieldInfo field in fields)
            {
                yield return field.GetValue(instance);
            }
        }
    }
    

    使用示例:

    Stuff myStuff = new Stuff { A = 1, B = 2.5f, C = 3, D = 4.8f, E = 5 };
    var floatFields = MemberHelper.GetTypedFieldValues<float>(myStuff);
    // 这里会得到B和D的值:2.5f、4.8f
    
  • 如果需要同时包含属性,只需要补充属性的筛选逻辑:

    public static IEnumerable<object> GetTypedMemberValues<T>(object instance)
    {
        if (instance == null) throw new ArgumentNullException(nameof(instance));
        
        Type type = instance.GetType();
        
        // 处理字段
        foreach (FieldInfo field in type.GetFields(BindingFlags.Public | BindingFlags.Instance)
                                        .Where(f => f.FieldType == typeof(T)))
        {
            yield return field.GetValue(instance);
        }
        
        // 处理可读属性
        foreach (PropertyInfo prop in type.GetProperties(BindingFlags.Public | BindingFlags.Instance)
                                         .Where(p => p.PropertyType == typeof(T) && p.CanRead))
        {
            yield return prop.GetValue(instance);
        }
    }
    
问题2:实现Stuff类的AllMyFloats属性

针对你的Stuff类,有两种实现思路,你可以根据需求选择:

方案1:手动列举(性能更优,适合成员固定的场景)

如果你的float类型字段不会频繁新增,直接手动把B、D加入列表就好,这种方式没有反射带来的性能开销:

public class Stuff 
{ 
    public int A; 
    public float B; 
    public int C; 
    public float D; 
    public int E; 
    
    public List<float> AllMyFloats 
    { 
        get 
        {
            return new List<float> { B, D };
        } 
    } 
}

方案2:反射实现(更灵活,适合成员可能新增的场景)

如果后续可能会添加更多float类型的字段,用反射自动收集就不用每次修改AllMyFloats的代码,直接复用问题1的逻辑即可:

public class Stuff 
{ 
    public int A; 
    public float B; 
    public int C; 
    public float D; 
    public int E; 
    
    public List<float> AllMyFloats 
    { 
        get 
        {
            return GetTypedFieldValues<float>(this).Cast<float>().ToList();
        } 
    }
    
    // 把工具方法作为类的私有方法
    private IEnumerable<object> GetTypedFieldValues<T>(object instance)
    {
        if (instance == null) throw new ArgumentNullException(nameof(instance));
        
        Type type = instance.GetType();
        FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.Instance)
                                 .Where(f => f.FieldType == typeof(T))
                                 .ToArray();
        
        foreach (FieldInfo field in fields)
        {
            yield return field.GetValue(instance);
        }
    }
}

这样不管后续新增多少个float类型的公共字段,AllMyFloats都会自动把它们包含进去~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 08:22:53