最近在写一个使用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 方法来模拟属性。
当我用 .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/