Jos*_*eph 5 .net c# reflection
最近在写一个方法,用反射构造类之间的依赖关系图,发现了如下问题。我的方法分析属性的返回类型、类定义的通用参数和这些类的实例字段。
为了检查类的实例字段,我使用以下方法。
public static IEnumerable<FieldInfo> GetFields(Type classType)
{
return classType
.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
}
Run Code Online (Sandbox Code Playgroud)
为了测试它,我编写了以下类定义:
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; }
}
Run Code Online (Sandbox Code Playgroud)
我震惊了几秒钟,看看结果。正是在我想起 .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;
}
Run Code Online (Sandbox Code Playgroud)
所以我修改了方法以排除具有 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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
问题
您可以在此处下载完整的代码。
小智 3
您需要的字段是:!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;
}
Run Code Online (Sandbox Code Playgroud)