我试图使用汇编中的反射来获取公共字段.
程序集只包含一个类,如下所示:
public abstract class User
{
private object _iAmPrivateField;
protected object IAmProtectedField;
internal object IAmInternalField;
public object IAmPublicField;
private void IAmPrivateMethod() { }
protected void IAmProtectedMethod() { }
internal void IAmInternalMethod() { }
public void IAmPublicMethod() { }
private object IAmPrivateProperty { get; set; }
protected object IAmProtectedProperty { get; set; }
internal object IAmInternalProperty { get; set; }
public object IAmPublicProperty { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
这是从给定程序集中检索公共字段的方法:
public FieldInfo[] GetPublic(Assembly assembly)
{
return assembly.GetTypes()
.SelectMany(x => x.GetFields(BindingFlags.Public | BindingFlags.Instance))
.Where(x => x.IsPublic).ToArray();
}
Run Code Online (Sandbox Code Playgroud)
上面的例子按预期工作 - 结果是1.
但是我在类中添加了异步方法
public async Task IAmAsyncMethod() { }
Run Code Online (Sandbox Code Playgroud)
经过上述更改后,GetPublic()返回4而不是1.
是否有选项可以过滤GetFields()仍然返回1的这些字段?
异步通过发出包含有关异步状态机的信息的额外类来工作.如果使用反汇编程序(如ILSpy)检查程序集,则可以看到它.有关此概念的更多信息,请参阅https://www.markopapic.com/csharp-under-the-hood-async-await/或Google"c#async state machine".还为使用的方法生成状态机yield return ...
这是您自动生成的异步状态机的样子,由ILSpy反编译:
[CompilerGenerated]
[Serializable]
private sealed class <>c
{
public static readonly Program.<>c <>9 = new Program.<>c();
public static Func<Type, IEnumerable<FieldInfo>> <>9__0_0;
public static Func<FieldInfo, bool> <>9__0_1;
internal IEnumerable<FieldInfo> <Main>b__0_0(Type x)
{
return x.GetFields(BindingFlags.Instance | BindingFlags.Public);
}
internal bool <Main>b__0_1(FieldInfo x)
{
return x.IsPublic;
}
}
Run Code Online (Sandbox Code Playgroud)
您可以通过检查来省略特殊的自动生成的类CompilerGeneratedAttribute.将您的代码修改为:
return assembly.GetTypes()
.Where(t => t.GetCustomAttribute<CompilerGeneratedAttribute>() == null)
.SelectMany(x => x.GetFields(BindingFlags.Public | BindingFlags.Instance))
.Where(x => x.IsPublic)
.ToArray();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
75 次 |
| 最近记录: |