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

如何以兼容裁剪的方式从表达式获取子类的PropertyInfo

.NET7裁剪场景下获取子类属性信息的代码兼容问题

背景

需要实现从表达式中获取子类的属性信息(而非基类的),用于Blazor组件库的表单模型属性获取。现有代码已满足功能需求,但在.NET7裁剪模式下触发了链接器警告。

现有实现代码

/// <summary>
/// Extracts the PropertyInfo for the property being accessed in the given expression.
/// </summary>
/// <remarks>
/// If possible, the actual owning type of the property is used, rather than the declaring class (so if "x" in "() => x.Foo" is a subclass overriding "Foo", then x's PropertyInfo for "Foo" is returned rather than the declaring base class's PropertyInfo for "Foo").
/// </remarks>
/// <typeparam name="T"></typeparam>
/// <param name="propertyExpression"></param>
/// <returns></returns>
internal static PropertyInfo ExtractPropertyInfo<T>(Expression<Func<T>> propertyExpression)
{
    if (propertyExpression == null)
    {
        throw new ArgumentNullException("propertyExpression");
    }

    var memberExpression = propertyExpression.Body as MemberExpression;
    if (memberExpression == null)
    {
        throw new ArgumentException(string.Format("Expression not a MemberExpresssion: {0}", propertyExpression), "propertyExpression");
    }

    var property = memberExpression.Member as PropertyInfo;
    if (property == null)
    {
        throw new ArgumentException(string.Format("Expression not a Property: {0}", propertyExpression), "propertyExpression");
    }

    var getMethod = property.GetGetMethod(true);
    if (getMethod.IsStatic)
    {
        throw new ArgumentException(string.Format("Expression cannot be static: {0}", propertyExpression), "propertyExpression");
    }

    Type realType = memberExpression.Expression.Type;
    if(realType == null) throw new ArgumentException(string.Format("Expression has no DeclaringType: {0}", propertyExpression), "propertyExpression");

    return realType.GetProperty(property.Name);
}

核心逻辑

获取子类类型的关键代码:

Type realType = memberExpression.Expression.Type;

.NET7裁剪模式下的警告问题

链接器对代码中return realType.GetProperty(property.Name);一行发出如下警告:

(local variable) PropertyInfo property
'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicProperties' in call to 'System.Type.GetProperty(String)'. The return value of method 'System.Linq.Expressions.Expression.Type.get' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. [MudBlazor]csharp(IL2075)

原因:GetProperty方法标注了DynamicallyAccessedMemberTypes.PublicProperties,但从memberExpression.Expression.Type获取的Type对象没有匹配的注解,导致裁剪器无法跟踪完整的注解依赖链。

疑问

  1. 能否修改这段代码,使其兼容.NET7的裁剪机制?
  2. 如果忽略该警告,裁剪器是否会保留包括子类在内的相关类型?

已尝试查看.NET Core中Type的实现,发现其基于内部字典且无法重写,也未找到其他兼容裁剪的子类类型确定方式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 15:20:22