Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is the "this" pointer null in a delegate?

Tags:

c#

.net

I have the following code (details removed for clarity):

    private abstract class Base<TResult> {
        private readonly System.Func<TResult> func = null;

        protected Base(System.Func<TResult> func) {
            this.func = func;
        }

        public TResult Execute() {
            return this.func();
        }
    }

    private class Derived : Base<bool> {
        public Derived(bool myValue) : base(delegate() { return this.MyValue(); }) {
            this.myValue = myValue;
        }

        private bool myValue = false;
        private bool MyValue() {
            return this.myValue; // The "this" pointer is null here...
        }
    }

    Derived d = new Derived(true);
    bool result = d.Execute(); // This results in a null reference pointer (commented above)

Any ideas?

Thanks, Dave

like image 950
Dave Avatar asked Aug 03 '10 13:08

Dave


2 Answers

Is that even legal? this is not defined at that point. IIRC, this is a compiler bug - already fixed in 4.0.

Here it is in the 4.0 compiler:

Error 1 Keyword 'this' is not available in the current context C:\Users\Marc\AppData\Local\Temporary Projects\ConsoleApplication1\Program.cs 22 40 ConsoleApplication1

To quote 7.5.7:

A this-access is permitted only in the block of an instance constructor, an instance method, or an instance accessor. It has one of the following meanings:

(emph mine)

...

Use of this in a primary-expression in a context other than the ones listed above is a compile-time error. In particular, it is not possible to refer to this in a static method, a static property accessor, or in a variable-initializer of a field declaration.

In the example given, it it simply invalid.

like image 57
Marc Gravell Avatar answered Sep 19 '22 14:09

Marc Gravell


Using this in a constructor is always dangerous (except in the special case where you are invoking a sibling constructor). Your Derived constructor captures this at the time of its invocation, which is null as the instance hasn't been constructed yet.

like image 31
Craig Stuntz Avatar answered Sep 19 '22 14:09

Craig Stuntz