Order by with LINQ to Reflection using MetadataToken and Lambda in C#

DISCLAIMER: Most if not all of the methods used with Reflection do not return their result in neither alphabetical or declaration order. This is clearly stated within the MSDN library remarks for the reflection methods. If you can avoid designing based on an expected order of results from any Reflection method, that would be best practice.

I had built a very nice program that used reflection where I had gone against the suggestion not to depend on the order or results from methods. It was working fine for quit some time. It stopped working. Initially, the order of the results from the GetTypes() and GetProperties() methods were returining the result in order of declaration and I have not idea what changed to make it stop working.

So I searched the internet, like always, and didn’t find a lot about this topic. However, I found enough to come up with this solution which works for me. The below is the original LINQ to Reflection that worked for me initially and then stopped working at some point.

[sourcecode language="csharp"]
var SCTypes = from type in assembly.GetTypes()
              where type.IsPublic
              from properties in type.GetProperties()
              group properties.ToString() by type.ToString();
[/sourcecode]

Here is the code which I now run to ordered the results from a Reflection method in declaration order. In this test case, both LINQ queries return the same results. However, in my actual implementation where the order was needed, the below ordered it correctly. Please read DISCLAIMER again. There is still no guarantee that another issue will popup in the future.

[sourcecode language="csharp"]
var SCTypes = from type in assembly.GetTypes()
                        .OrderBy(t => t.MetadataToken)
              where type.IsPublic
              from properties in type.GetProperties()
                        .OrderBy(p => p.MetadataToken)
              group properties.ToString()
                by type.ToString();
[/sourcecode]

You see I have simply added an OrderBy method to the GetTypes() method. The t represents the results of the GetTypes() method and then it “goes to” the t.MetadataToken expression.

Top display the results you just need to place it within a foreach statement.

[sourcecode language="csharp"]
foreach (var SCMethods in SCTypes)
{
    Console.WriteLine("Type: {0}", SCMethods.Key);
    foreach (var method in SCMethods)
    {
       Console.WriteLine(" Property: {0}", method);
     }
}
[/sourcecode]

Like I mentioned, both of the above LINQ queries, in this example, returned the same thing for me. However, if you experience unordered results from a Reflection method, you can give it a try and see if it works for you. If you download the code, you need to put the SimpleClass.dll into your projects bin\Debug directory.

Download the source




Leave a Comment

Your email address will not be published.