jbevain / mono.reflection

Some useful reflection helpers, including an IL disassembler.
150 stars 50 forks source link

Operation is not valid due to the current state of the object. on .GetBackingfield() #1

Closed joergbattermann closed 14 years ago

joergbattermann commented 14 years ago

Hey there,

I am playing a little with Mono.Reflection in a .Net 3.5 project to get a Property's BackingField and its attributes. However, the propertyInfo.GetBackingField() method throws an InvalidOperationException... :-/

Sample Code:

var propertyInfos = myObject.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

foreach (var propertyInfo in propertyInfos) { var backingField = propertyInfo.GetBackingField(); // >> throws System.InvalidOperationException }

More details:

Source: "Mono.Reflection" Message: "Operation is not valid due to the current state of the object."

StackTrace: at Mono.Reflection.BackingFieldResolver.GetBackingField(MethodInfo method, ILPattern pattern) at Mono.Reflection.BackingFieldResolver.GetBackingField(PropertyInfo self)

TargetSite: "System.Reflection.FieldInfo GetBackingField(System.Reflection.MethodInfo, Mono.Reflection.ILPattern)"

Any ideas why this is happening?

-J

jbevain commented 14 years ago

It's possible that you're hitting an indexer. Currently GetBackingField works only for traditional properties. Could you paste the code of the property that triggers the exception ?

joergbattermann commented 14 years ago

Oh now that was quick :)

The property & backingfield are the following:

private string _department;

    /// <summary>
    /// Gets or sets the department.
    /// </summary>
    /// <value>The department.</value>
    public string Department
    {
        get
        {
            Activate(ActivationPurpose.Read);
            return _department;
        }
        set
        {
            Activate(ActivationPurpose.Write);
            _department = value;
        }
    }

(it's using db4o's transparent activation mechanism in the Property there)

jbevain commented 14 years ago

GetBackingField reads the IL of the property to find a certain pattern, specific to simple properties. As you have calls to methods in them, they stop being simple properties.

Now, it's possible to write a custom IL pattern to look for. That's your lucky day, I already wrote the pattern for db4o properties here:

http://source.db4o.com/db4o/trunk/db4o.net/Db4objects.Db4o.Linq/Db4objects.Db4o.Linq/CodeAnalysis/ReflectionMethodAnalyser.cs

joergbattermann commented 14 years ago

Nice! Thanks Jean-Baptiste for the quick help!