2011-06-21 23 views
5

Me encuentro con lo que creo que es un error y me preguntaba si esto ya es conocido como un problema o si esto no es un problema y por qué.VB.Net ¿por qué no es esto un error?

El problema relacionado con Leer propiedades de sólo en un tipo al compilar con el compilador de VB.Net en Visual Studio 2008.

que sigue son las definiciones de clase y un pequeño programa en C# que no se compilará. (Y es correcto en mi humilde opinión no compilar debido a la propiedad que se encuentra en el Delegado es de sólo lectura)

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

en VB.Net Sin embargo, esto es un problema más grande ... el programa compilar y ejecutar sin excepción. Pero la propiedad no está establecida. Esto fue una pesadilla para atrapar en el depurador en tiempo de ejecución y creemos que el compilador debería haber entendido que estamos asignando una propiedad solo lista tal como el compilador CSharp lo alerta cuando compila.

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 

¿Alguien puede explicar si esta es la lógica correcta y por qué?

Supongo que alguien responderá que el trabajo del compilador se cumplió al examinar el tipo de parámetro para el delegado y que el delegado se tipeó para aceptar ese parámetro como debería al analizar un cuerpo de método o un cuerpo de función.

Mi réplica a esto sería que el compilador arroja un error cuando se intenta establecer esa propiedad desde un método pero no desde el delegado. Los delegados deben analizarse de la misma manera que un Método.

¿Se ha extendido el compilador C#? Yo creo que no. Mi experiencia es que este es un error en el compilador de vb.net y debería arreglarse con un parche en el IDE.

Por último, pero no menos importante, ¿qué ocurre cuando ocurre la invocación?

El delegado seguramente no utiliza el reflejo para establecer la propiedad automágicamente así que supongo que CLR ve el calificador de solo lectura y se ejecuta un NOOP. ¿Es eso realmente lo que ocurre o es el comportamiento indefinido?

¡Gracias por su tiempo!

Respuesta

5

En VB.NET 2008, no hay ninguna declaración lambdas. Todas las lambdas son funciones. Devuelven un valor, no realizan una acción.

Su VB lambda simplemente compara d.PrivateBool y False y devuelve el resultado de la comparación.

Esto no es un error y por diseño. Por lo tanto, es aconsejable evitar asignar las lambdas de VB.NET 2008 a Action, esto es muy confuso para una persona no preparada.

lambdas declaración apareció en VB.NET 2010.

+0

lo que el compilador se infiere que una evaluación o comparación que está sucediendo y no una cesión? Si la acción no puede tener un valor de retorno porque es igual a un Void o Sub, entonces, ¿cómo puede devolver bool? – Jay

+0

@Jay Sí, el compilador sabe que es una comparación. El valor de retorno se ignora, porque es una 'Acción'. Está perfectamente bien llamar a una función desde un sub y simplemente ignorar el valor de retorno, lo has visto en código no lambda muchas veces. – GSerg