2011-06-21 28 views
5

私はバグであると信じているものに遭遇し、これが既に問題として知られているのか、それとも問題ではないのか、なぜそれが問題なのか疑問に思っていました。VB.Netなぜこれはバグではありませんか?

を次のVisual StudioでVB.Netのコンパイラでコンパイルするときの種類にのみ、プロパティの読み取りに関連する問題は、クラス定義とコンパイルされません小さなC#プログラムです。 (デリゲートに設定されているプロパティは読み取り専用であるため私見コンパイルしないで正しい)VB.Netで

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

しかし、これは大きな問題です...プログラムのコンパイルと例外なく実行されます。しかし、このプロパティは設定されていません。 これは、実行時にデバッガを捕まえるのは難しいことでした。私たちは、コンパイル時に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が実行されると仮定します。それは実際に何が起こるのか、それとも未定義の行動ですか?

ありがとうございました!

答えて

5

VB.NET 2008にはステートメントラムダはありません。すべてのラムダは関数です。値を返し、アクションを実行しません。

VBラムダはd.PrivateBoolFalseを単純に比較し、比較結果を返します。

これはバグではなく、設計によるものです。したがって、VB.NET 2008のラムダをActionに割り当てることを避けることをお勧めします。これは、準備ができていない人にとっては非常に混乱します。

ステートメントラムダだから、コンパイラは、評価や比較が割り当てを起こっしていないことを推測さ

+0

VB.NET 2010年に登場しましたか? VoidまたはSubと等しいためにアクションが戻り値を持てない場合、どうすればboolを返すことができますか? – Jay

+0

@Jayはい、コンパイラはそれが比較であることを知っています。戻り値は 'Action'なので無視されます。サブ関数から関数を呼び出すだけで、戻り値を無視するのはまったく問題ありません。何回でも非λコードで見たことがあります。 – GSerg

関連する問題