gpt4 book ai didi

c# - 获取不是由编译器生成的反射字段

转载 作者:行者123 更新时间:2023-11-30 12:25:24 24 4
gpt4 key购买 nike

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

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

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 .

最佳答案

您需要的字段是:!field.IsDefined(typeof(CompilerGeneratedAttribute), false)

public static IEnumerable<FieldInfo> GetFields(Type classType)
{
var allFields = classType
.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

var definedFields = from field in allFields
where !field.IsDefined(typeof(CompilerGeneratedAttribute), false)
select field;

return definedFields;
}

关于c# - 获取不是由编译器生成的反射字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31528140/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com