4

I encounter what I believe to be a bug and I was just wondering if this is already known as a issue or if this is not a issue and why.

The problem related to Read Only Properties on a Type when compiling with the VB.Net Compiler in Visual Studio 2008.

Follows are the class definitions and a small C# program which will not compile. (And is correct in not compiling IMHO because the property being set in the Delegate is Read-only)

public interface ITest
{
    bool PrivateBool { get; }
}

public class TestClass : ITest
{
    bool privateBool = false;

    public bool PrivateBool
    {
        get
        {
            return privateBool;
        }
    }

    bool publicBool = false;

    public bool PublicBool
    {
        get { return publicBool; }
        set { publicBool = value; }
    }
}

class Program
{
    static void Main(string[] args)
    {
        TestClass tc = new TestClass();
        //Compile Error
        //tc.PrivateBool = false;

        //Compile Error
        //Action act = new Action(delegate()
        //{
        //    tc.PrivateBool = false;
        //});

        //Action<TestClass> test = new Action<TestClass>(delegate(TestClass tcc)
        //{
        //    tcc.PrivateBool = false;               
        //});

        //Compile Time Error
        //Action<TestClass> test = new Action<TestClass>( tz=> tz.PrivateBool = false);

        //Compile Time Error
        //Action test = new Action(tc.PrivateBool = false);
    }
}

In VB.Net However this is a larger issue… the program will compile and execute with no exception. But the property is not set. This was a nightmare to catch in the debugger at Run time and we feel that the compiler should have caught that we are assigning to a ready only property just as the CSharp compiler alerts you when compiling.

Module Module1

    Sub Main()

        Dim tc As New TestClass()
        Dim setP = New Action(Of TestClass)(Function(d As TestClass) _
                                                d.PrivateBool = False _
                                                )

        setP.Invoke(tc)


    End Sub

End Module

Can anyone explain if this is correct logic and why?

I assume that someone will respond that the job of the compiler was fulfilled by examining the parameter type to the delegate and that the delegate was typed to accept that parameter just as it should when parsing a Method Body or a Function Body.

My rebuttal to this would be that the compiler DOES throw an error when that property is attempted to be set from within a method but not the delegate. Delegates should be parsed the same as a Method.

Is the C# compiler over extending itself? I think not. My experience is that this is a bug in the vb.net compiler and should be fixed by a patch to the IDE.

Last but surely not least what occurs when the Invoke happens?

The delegate surely does not use reflection to set the property automagically so I assume the CLR sees the read-only qualifier and a NOOP gets executed. Is that actually what occurs or is the behavior undefined?

Thank you for your time!

Jay
  • 3,276
  • 1
  • 28
  • 38

1 Answers1

5

In VB.NET 2008, there are no statement lambdas. All lambdas are functions. They return a value, not perform an action.

Your VB lambda simply compares d.PrivateBool and False and returns the result of the comparison.

This is not a bug and by design. It is therefore advisable to avoid assigning VB.NET 2008's lambdas to an Action, this is highly confusing for an unprepared person.

Statement lambdas appeared in VB.NET 2010.

GSerg
  • 76,472
  • 17
  • 159
  • 346
  • So the compiler is inferring that a evaluation or comparison is happening and not an assignment? If action can have no return value because it is equal to a Void or Sub then how can it return bool? – Jay Jun 21 '11 at 22:40
  • @Jay Yes, the compiler knows it is a comparison. The return value is ignored, because it's an `Action`. It's perfectly fine to call a function from a sub and just ignore the return value, you have seen it in non-lambda code many times. – GSerg Jun 21 '11 at 22:46