The way to solve this problem is to look directly at the generated IL of the type that you know has dynamic properties. There you will find that such a property is represented simply as an object type, but also all of its components are decorated with the DynamicAttribute attribute.
This attribute is put in place by the compiler itself, and can not be used by the developer. Thus, the only thing you need to do is to check if a property is decorated with the DynamicAttribute attribute.
To see this, take a look at the following IL code for the IamDynamic property's Get accessor method, which we will use later for testing purposes.
.method public hidebysig specialname instance object
get_IamDynamic() cil managed
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
.param [0]
.custom instance void [System.Core]System.Runtime.CompilerServices.DynamicAttribute::.ctor() = ( 01 00 00 00 )
.maxstack 1
.locals init (object V_0)
IL_0000: ldarg.0
IL_0001: ldfld object Testing.TestClass::'<IamDynamic>k__BackingField'
IL_0006: stloc.0
IL_0007: br.s IL_0009
IL_0009: ldloc.0
IL_000a: ret
You can easily notice the line where the DynamicAttribute is used, indicating that this is a dynamic declaration. We can now discover all the dynamic properties by using the following extension method.
public static class DynamicExtension
{
public static void GetDynamicProperties(this Type source)
{
source.GetProperties()
.Where(x => x.GetCustomAttributes().OfType<DynamicAttribute>().Any())
.ToList()
.ForEach(x => Console.WriteLine(x.Name));
}
}
This class, that was mentioned above will be tested for dynamic properties.
class TestClass
{
public dynamic IamDynamic { get; set; }
public object IamNotDynamic { get; set; }
public dynamic IamAlsoDynamic { get; set; }
}
Once you execute the following lines of code, you will see that only the two dynamic properties are displayed.
class Program
{
static void Main()
{
typeof(TestClass).GetDynamicProperties();
Console.Read();
}
}