VB.Net почему это не ошибка? - PullRequest
4 голосов
/ 22 июня 2011

Я сталкиваюсь с тем, что я считаю ошибкой, и мне просто интересно, если это уже известно как проблема или это не проблема, и почему.

Проблема, связанная со свойствами только для чтения наВведите при компиляции с помощью компилятора VB.Net в Visual Studio 2008.

Ниже приведены определения классов и небольшая программа на C #, которая не будет компилироваться.(И правильно не компилировать IMHO, потому что свойство, устанавливаемое в Delegate, доступно только для чтения)

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);
    }
}

В VB.Net Однако это более серьезная проблема… программа будет компилироваться и выполняться без исключения,Но свойство не установлено.Это был кошмар, чтобы поймать отладчик во время выполнения, и мы считаем, что компилятор должен был отловить, что мы присваиваем свойство «только готово» так же, как компилятор CSharp предупреждает вас при компиляции.

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

Можеткто-нибудь объяснит, если это правильная логика и почему?

Я предполагаю, что кто-то ответит, что задание компилятора было выполнено путем проверки типа параметра для делегата и что делегат был напечатан так, чтобы принимать этот параметр так же, какэто должно происходить при синтаксическом анализе тела метода или тела функции.

Я бы опроверг это, когда компилятор выдает ошибку, когда это свойство пытается быть установлено из метода, но не из делегата.Делегаты должны анализироваться так же, как и метод.

Является ли компилятор C # сверх себя?Думаю, нет.Мой опыт показывает, что это ошибка в компиляторе vb.net, и она должна быть исправлена ​​патчем в IDE.

Последнее, но не менее важное, что происходит, когда происходит Invoke?

Конечно, делегат не использует рефлексию для автоматической установки свойства, поэтому я предполагаю, что CLR видит квалификатор «только для чтения» и выполняется NOOP.Это действительно то, что происходит, или поведение не определено?

Спасибо за ваше время!

1 Ответ

5 голосов
/ 22 июня 2011

В VB.NET 2008 нет лямбда-выражений операторов. Все лямбды являются функциями. Они возвращают значение, а не выполняют действие.

Ваша VB лямбда просто сравнивает d.PrivateBool и False и возвращает результат сравнения.

Это не ошибка и по замыслу. Поэтому желательно не назначать лямбды VB.NET 2008 на Action, это очень запутанно для неподготовленного человека.

Заявление лямбды появилось в VB.NET 2010.

...