如何获取类实例中指定类型的所有成员并通过属性返回?
嘿,这就来帮你搞定这两个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
相关产品推荐
相关产品推荐

