[Mono-dev] Mono's reflection implementation

Kris Mok rednaxela0607 at hotmail.com
Thu Sep 10 03:53:53 EDT 2009


Hi all,

I was trying out some tricks and needed reflection to pull them off. But 
when I tried to retrieve private instance fields of an object, I found a 
difference in behavior on Type.GetFields between Microsoft's CLR and Mono. I 
tried this on Ubuntu 9.04 with Mono 2.0.1 from apt-get, and Mono 2.4.3.2 
from source tarball.

Here's a repro:

using System;
using System.Reflection;

static class Program {
    static void PrintNonPublicInstanceFields(Type type) {
        Console.WriteLine("non-public instance fields of {0}", type);
        var mInfos = type.GetFields(BindingFlags.NonPublic | 
BindingFlags.Instance);
        if (0 == mInfos.Length) Console.WriteLine("mInfos is empty");
        foreach (var mi in mInfos) {
            Console.WriteLine(mi);
        }
    }

    static void Main(string[] args) {
        // Mono 2.0.1 doesn't handle GetFields correctly:
        // it only searches declared ones, not inherited ones
        // Mono 2.4.3.2 behaves the same...
        PrintNonPublicInstanceFields(typeof(Func<int, int>));
        Console.WriteLine();
        PrintNonPublicInstanceFields(typeof(Delegate));
    }
}

On Mono, the program's output is:
non-public instance fields of System.Func`2[System.Int32,System.Int32]
mInfos is empty

non-public instance fields of System.Delegate
System.IntPtr method_ptr
System.IntPtr invoke_impl
System.Object m_target
System.IntPtr method
System.IntPtr delegate_trampoline
System.IntPtr method_code
System.Reflection.MethodInfo method_info
System.Reflection.MethodInfo original_method_info
System.DelegateData data

where as on Microsoft's CLR, the output is:
non-public instance fields of System.Func`2[System.Int32,System.Int32]
System.Object _target
System.Reflection.MethodBase _methodBase
IntPtr _methodPtr
IntPtr _methodPtrAux

non-public instance fields of System.Delegate
System.Object _target
System.Reflection.MethodBase _methodBase
IntPtr _methodPtr
IntPtr _methodPtrAux

I know the difference in actual private fields is due to different internal 
implementations, what I'm trying to say is that Mono's Type.GetFields 
doesn't return inherited fields.

According to Mono's documentation, here:
http://go-mono.org/docs/monodoc.ashx?link=M%3aSystem.Type.GetFields(System.Reflection.BindingFlags)
it says: System.Reflection.BindingFlags.DeclaredOnly to search only the 
fields declared in the type, not fields that were simply inherited.
I thought this should imply Type.GetFields will return inherited fields if I 
don't call it with BindingFlags.DeclaredOnly. Is the current behavior 
by-design or a bug? 



More information about the Mono-devel-list mailing list