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

如何区分C#子类中继承属性与自身定义的属性?

解决子类属性与父类继承属性的区分问题

这问题我之前踩过坑!你用Except没效果的核心原因是:PropertyInfo实例的引用相等性不等于属性的逻辑相等性。子类继承来的属性对应的PropertyInfo对象,和父类中定义该属性的PropertyInfo对象不是同一个实例,所以Except默认的引用比较会把它们当成不同的元素,自然没法过滤掉继承属性。

最简单的解决方案:用DeclaringType过滤

直接通过PropertyInfo.DeclaringType属性判断,这个属性会返回定义该属性的原始类。子类自身定义的属性,DeclaringType就是typeof(Child);继承来的属性则是父类的类型(这里是typeof(Father))。

代码示例:

var childOwnProperties = typeof(Child).GetProperties()
    .Where(p => p.DeclaringType == typeof(Child));

运行这段代码,只会返回Child类自己定义的Name属性,完美过滤掉从Father继承来的Id和Price。

为什么你的原代码不行?

当你调用typeof(Child).GetProperties()时,返回的继承属性(比如Id)的PropertyInfo实例,虽然它代表的是父类定义的属性,但这个实例和typeof(Father).GetProperties()返回的Id属性实例是不同的对象。Except默认用Object.Equals做引用比较,所以会认为这两个是不同的元素,不会排除它们。

进阶:自定义相等比较器用Except

如果你一定要用Except方法,可以自定义一个IEqualityComparer<PropertyInfo>,根据属性的逻辑标识来判断相等性(比如属性名称+属性类型,或者更严谨的元数据标识):

public class PropertyInfoEqualityComparer : IEqualityComparer<PropertyInfo>
{
    public bool Equals(PropertyInfo x, PropertyInfo y)
    {
        if (x == null || y == null) return x == y;
        // 比较属性的名称和类型,确保逻辑上是同一个属性
        return x.Name == y.Name && x.PropertyType == y.PropertyType;
    }

    public int GetHashCode(PropertyInfo obj)
    {
        return obj.Name.GetHashCode() ^ obj.PropertyType.GetHashCode();
    }
}

然后这样使用:

var childProperties = typeof(Child).GetProperties()
    .Except(typeof(Father).GetProperties(), new PropertyInfoEqualityComparer());

不过这种方法不如直接用DeclaringType过滤简洁直观,除非你有特殊场景需要用Except。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:52:10