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

ASP.NET MVC反射中如何判断MethodInfo的CallingConvention为Standard|HasThis?

问题:ASP.NET MVC反射场景下判断类是否不存在标准非静态公共Getter

我正在开发一个ASP.NET MVC项目,处理反射相关功能时,需要判断某个类是否不存在标准的非静态公共getter,编写了如下代码:

public static bool NotHavePublicGetter(Type deger, string propertyName)
{
    try
    {
        if (deger == null)
            throw new ArgumentNullException("Type");

        if (string.IsNullOrEmpty(propertyName))
            throw new ArgumentNullException(typeof(string).ToString());

        PropertyInfo[] propertyInfoDizisi = deger.GetProperties(BindingFlags.Public | BindingFlags.Instance);

        if (propertyInfoDizisi == null || !propertyInfoDizisi.Any())
            throw new InvalidOperationException("propertyInfoDizisi == null || !propertyInfoDizisi.Any()");

        MethodInfo getterMethodInfo = null;

        StringBuilder getDotNetName = new StringBuilder();
        getDotNetName.Append("get_");
        getDotNetName.Append(propertyName);

        foreach (PropertyInfo propertyInfo in propertyInfoDizisi)
        {
            if (propertyInfo == null)
                continue;                  

            getterMethodInfo = propertyInfo.GetGetMethod(false);
            
            if (getterMethodInfo == null)
                continue;
            
            // 此处需要检查getterMethodInfo的CallingConvention属性
            if (getDotNetName.ToString().Equals(getterMethodInfo.Name))
                return false;
        }

        return true;
    }
    catch (ArgumentNullException hata)
    {
        //TODO productionda kalkacak. 
        //YAP2 testte aktive edilecek. 
        throw hata;
    }
    catch (InvalidOperationException hata)
    {
        //TODO productionda kalkacak. 
        //YAP2 testte aktive edilecek. 
        throw hata;
    }
    catch (Exception hata)
    {
        //TODO productionda kalkacak. 
        //YAP2 testte aktive edilecek. 
        throw hata;
    }

    //TODO productionda aktive gelecek.
    //YAP2 testte deaktive edilecek. 
    //return true;
}

调试时发现getterMethodInfo.CallingConvention的属性值为Standard | HasThis,但用getterMethodInfo.CallingConvention == CallingConventions.Standard || getterMethodInfo.CallingConvention == CallingConventions.HasThis判断时返回false,请问如何正确检查该属性是否为Standard | HasThis?


解决方案

这是因为CallingConventions是带有FlagsAttribute的枚举类型,多个枚举值通过按位或组合,不能直接用相等运算符==判断单个值。正确的检查方式有两种:

1. 使用按位与运算判断组合值

通过按位与运算,验证目标枚举值是否同时包含Standard和HasThis:

// 定义需要检查的组合约定
var requiredConventions = CallingConventions.Standard | CallingConventions.HasThis;
// 按位与运算验证是否包含全部约定
if ((getterMethodInfo.CallingConvention & requiredConventions) == requiredConventions)
{
    if (getDotNetName.ToString().Equals(getterMethodInfo.Name))
        return false;
}

2. 使用HasFlag方法(.NET Framework 4.0+支持)

HasFlag方法可以直接判断枚举是否包含指定的单个或组合值:

if (getterMethodInfo.CallingConvention.HasFlag(CallingConventions.Standard) 
    && getterMethodInfo.CallingConvention.HasFlag(CallingConventions.HasThis))
{
    if (getDotNetName.ToString().Equals(getterMethodInfo.Name))
        return false;
}

代码优化建议

你当前通过拼接get_前缀匹配getter方法名的方式可以简化,直接通过PropertyInfo.Name匹配目标属性名即可,无需操作方法名:

foreach (PropertyInfo propertyInfo in propertyInfoDizisi)
{
    if (propertyInfo == null)
        continue;

    // 直接匹配属性名,避免字符串拼接
    if (propertyInfo.Name != propertyName)
        continue;

    var getter = propertyInfo.GetGetMethod(false);
    if (getter == null)
        continue;

    // 检查调用约定
    var requiredConventions = CallingConventions.Standard | CallingConventions.HasThis;
    if ((getter.CallingConvention & requiredConventions) == requiredConventions)
    {
        // 存在符合要求的公共getter,返回false
        return false;
    }
}

这样代码更直观,也减少了不必要的字符串操作开销。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 01:05:54