I am trying to get public fields using reflection from assembly.
Assembly contain just one class as below:
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; }
}
This is the method which retrieves public fields from given assembly:
public FieldInfo[] GetPublic(Assembly assembly)
{
return assembly.GetTypes()
.SelectMany(x => x.GetFields(BindingFlags.Public | BindingFlags.Instance))
.Where(x => x.IsPublic).ToArray();
}
The above example is working as expected - the result is 1.
However I added async method inside the class
public async Task IAmAsyncMethod() { }
After above change, GetPublic()
returns 4 instead of 1.
Is there an option to filter these fields that GetFields()
still returns 1?
async works by emitting an extra class containing information about the async state machine. You can see it if you inspect the assembly using a disassembler such as ILSpy. For more information on this concept, see https://www.markopapic.com/csharp-under-the-hood-async-await/ or Google "c# async state machine". State machines are also generated for methods that use
yield return ...
This is what your auto-generated async state machine looks like, as decompiled by ILSpy:
You can omit special auto-generated classes like that by checking for the
CompilerGeneratedAttribute
. Amend your code as: