获取不是由编译器生成的Reflection字段

时间:2015-07-20 23:47:47

标签: c# .net reflection

最近我正在编写一个方法,使用Reflection构建一个包含类之间依赖关系的图,并发现了以下问题。我的方法分析了属性的返回类型,类定义的泛型参数和这些类的实例字段。

为了检查类I的实例字段,请使用以下方法。

public static IEnumerable<FieldInfo> GetFields(Type classType)
{
    return classType
        .GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
}  

为了测试它,我编写了以下类定义:

static void Main(string[] args)
{
    foreach (var fieldInfo in GetFields(typeof(A)))
        Console.WriteLine(fieldInfo.Name);

    Console.ReadKey();
}

class A
{
    private ulong? _field1;

    public byte PropertyA { get; set; }

    public int PropertyB { get; set; }

    public bool PropertyC { get; set; }
}

我震惊了几秒钟,看到了结果。当我记得.NET生成一个实例字段,Set和Get方法来模拟属性时。

enter image description here

当我用.NET Reflector库查看编译器生成的代码时,我发现了以下定义。

class A
{
    private ulong? _field1; 

    [CompilerGenerated]
    private Byte <PropertyA>k__BackingField;

    [CompilerGenerated]
    private Int32 <PropertyB>k__BackingField;

    [CompilerGenerated]
    private bool <PropertyC>k__BackingField;
}

所以我修改了方法以使用CompilerGenerated属性排除字段,并且他的名字与某些属性匹配。

public static IEnumerable<FieldInfo> GetFields(Type classType)
{
    var regex = new Regex(@"^<(?<PropertyName>\w+)>\w+$");

    var fieldInfoes = classType
            .GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

    foreach (var fieldInfo in fieldInfoes)
    {
        if (fieldInfo.GetCustomAttribute<CompilerGeneratedAttribute>() == null)
            yield return fieldInfo;
        else
        {
            var match = regex.Match(fieldInfo.Name);
            if (!match.Success) 
                continue;

            var propertyName = match.Groups[@"PropertyName"].Value;
            if (classType.GetProperty(propertyName) == null)
                yield return fieldInfo;
        }
    }
}

问题

  • 这些字段中缺少一些BindingFlags的组合吗?
  • 还有另一种获取这些字段的方法,因为这个代码在我看来就像用火箭筒杀死一只蚊子一样?

您可以下载完整的代码here

1 个答案:

答案 0 :(得分:1)

您需要以下字段:<a id="view:_id1:link1" href="#" class="xspLink" data-toggle="tab">Profiles</a>

!field.IsDefined(typeof(CompilerGeneratedAttribute), false)