如何用LINQ/Reflection获取SchoolStaff类中的非空子对象
问题描述
假设有如下C#类结构:
public class SchoolStaff { public JuniorStaff? juniorStaff { get; set; } public SeniorStaff? seniorStaff { get; set; } public AdministrativeStaff? administrativeStaff { get; set; } } public class AdministrativeStaff { public int administrativeStaffId { get; set; } } public class SeniorStaff { public int seniorStaffId { get; set; } } public class JuniorStaff { public int juniorStaffId { get; set; } }
已知SchoolStaff实例中三个属性始终仅有一个非空,其余为null,需要获取这个非空对象,能否通过LINQ或反射实现?
当然可以,两种实用方案如下:
方案1:手动枚举属性 + LINQ(性能更优)
如果属性数量固定且不多,直接把所有属性值放进集合,用LINQ筛选非空项最直接,性能也比反射好:
public object? GetNonNullStaff(SchoolStaff staff) { return new[] { staff.juniorStaff, staff.seniorStaff, staff.administrativeStaff } .FirstOrDefault(item => item != null); }
要是需要强类型返回,还可以加泛型约束做类型转换:
public T? GetNonNullStaff<T>(SchoolStaff staff) where T : class { return new[] { staff.juniorStaff, staff.seniorStaff, staff.administrativeStaff } .OfType<T>() .FirstOrDefault(); }
方案2:反射实现(通用性更强)
如果后续可能新增同类属性,用反射可以自动遍历符合条件的属性,不用每次修改筛选逻辑:
public object? GetNonNullStaff(SchoolStaff staff) { // 获取SchoolStaff中所有可空的公共实例属性 var properties = typeof(SchoolStaff).GetProperties(BindingFlags.Public | BindingFlags.Instance) .Where(p => !p.PropertyType.IsValueType || Nullable.GetUnderlyingType(p.PropertyType) != null); foreach (var prop in properties) { var value = prop.GetValue(staff); if (value != null) { return value; } } return null; }
如果要精准筛选指定的子类类型(比如只找JuniorStaff、SeniorStaff、AdministrativeStaff),可以加类型判断:
public object? GetNonNullStaff(SchoolStaff staff) { var targetTypes = new[] { typeof(JuniorStaff), typeof(SeniorStaff), typeof(AdministrativeStaff) }; var properties = typeof(SchoolStaff).GetProperties(BindingFlags.Public | BindingFlags.Instance) .Where(p => targetTypes.Contains(p.PropertyType)); foreach (var prop in properties) { var value = prop.GetValue(staff); if (value != null) { return value; } } return null; }
内容的提问来源于stack exchange,提问作者Syed
相关产品推荐
相关产品推荐

