2011-01-15 17 views
40

Formクラスの名前を表す(Name)プロパティがあることを知りたいだけです。このプロパティは、フォームがインスタンスであるクラスを一意に識別するために名前空間内で使用され、Visual Basicの場合はフォームの既定のインスタンスにアクセスするために使用されます。VB.Netではすべてのフォームのデフォルトインスタンスが存在しますが、C#ではデフォルトインスタンスが存在しないのはなぜですか?

ここで、このデフォルトインスタンスがどこから来たのか、なぜC#にはこれと同等のメソッドがありませんか?

// Only method 
Form1 frm = new Form1(); 
frm.Show(); 

しかし、VB.Netで、我々はそれを行うには、両方の方法があります:

' First common method 
Form1.Show() 

' Second method 
Dim frm As New Form1() 
frm.Show() 
  1. マイ

    はまた、C#でフォームを表示する例えば、私たちはこのような何かをこの最初の方法から質問が出ます。 Form1とは何ですか、それはForm1またはForm1クラスのインスタンスですか?今、私が上で述べたように、フォーム名はVB.NetのDefaultインスタンスです。しかし、Form1Designerで定義されたクラスなので、インスタンス名とクラス名の名前はどのように同じになるのでしょうか? Form1がクラスの場合、Show()という名前の(Static \ Shared)メソッドはありません。 この方法はどこから来たのですか?

  2. 発生したILの違いは何ですか?

  3. 最後に、なぜC#にこれに相当するものがありませんか?

+2

:あなた自身のために調べるために、.NETリフレクターをダウンロードして使用します。それは非常に便利で無料です。 –

+2

私はC#でこの "機能"を望んでいません...あなたがそれを使用するためにクラスのインスタンスを作成する必要があるという事実を隠すことは単なるトリックです。それは本当に恐ろしいアイデアです!さらに、それは非常によく文書化されておらず、予期しない危険な副作用を持っています(例えば、各スレッドが独自の "デフォルトインスタンス"を持っています) –

+0

@ThomasLevesque私はその機能を望んでいません。 :) –

答えて

31

これはVS2005付属のVB.NETのバージョンで言語に戻って追加されました。一般的な要求によって、VB6プログラマは、タイプとそのタイプのオブジェクトへの参照との間の違いを見るのに苦労しました。あなたのスニペットのForm1とfrmその歴史はありますが、VBはフォームがVB1に戻る途中でVB4までクラスを取得しませんでした。そうでなければ、プログラマーの心には全く問題がありません。その違いが非常にであり、効果的なオブジェクト指向コードを書くのに重要です。 C#にはこれがない理由の大きな部分です。

C#ではVB.NETのようにグローバルな名前空間にプロパティやメソッドを追加することができないため、C#でもこれを得ることができます。あなたはこのように、フォームのコードに接着剤のビットを追加することができます。

public partial class Form2 : Form { 
    [ThreadStatic] private static Form2 instance; 

    public Form2() { 
     InitializeComponent(); 
     instance = this; 
    } 

    public static Form2 Instance { 
     get { 
      if (instance == null) { 
       instance = new Form2(); 
       instance.FormClosed += delegate { instance = null; }; 
      } 
      return instance; 
     } 
    } 
} 

あなたはVB.NETでのForm2を使用することができます同じようにあなたが今、あなたのコードでForm2.Instanceを使用することができます。プロパティゲッターのifステートメントのコードは、それを効率的にするために独自のプライベートメソッドに移動する必要があります。

ちなみに、そのスニペットの[ThreadStatic]属性は、多くのVB.NETプログラマが完全な絶望でスレッドをあきらめた原因です。抽象が漏れているときの問題。 は本当にです。 「彼らは、生成ILに持ってどのような違い」

+0

私はそれをしないだろう;)..あなたの*接着剤のための多くの*それは私にそれが起こったもののより良い理解を与えた。 –

+3

VB.Netに追加された重要な理由は、既存のコードをVB1-3からVB.Netに移植するのを助けることでした。代替コードがないため、機能が使用されていました。だからこそ私はそれが追加されたことを嬉しく思います。個人的に私はそれを新しいコードで使うべきだとは思わない。また、この機能とVB6でのいくつかの経験に対する私のサポートにもかかわらず、タイプのインスタンスへの参照と型の違いを私が個人的に理解しているとは思えません:) – MarkJ

+2

基本的にVB.NET言語が変更されましたユーザーがOOPを理解するにはあまりにも愚かであったため、私はこの言語がC#とほぼ同じ機能を持っていますが、多くの点で欠陥があります。 –

23

VBは、基本的にあなたの背中の後ろにプロジェクトのコードを追加しています。

何が起こっているのかを確認する最も簡単な方法は、最小限のプロジェクトを作成し、反射板でそれを見ることです。私はちょうどVBで新しいWinFormsのアプリケーションを作成し、このクラスを追加しました:

Public Class OtherClass  
    Public Sub Foo() 
     Form1.Show() 
    End Sub 
End Class 

C#などの逆コンパイル時にfooのコンパイルされたコードは次のようになります。

public void Foo() 
{ 
    MyProject.Forms.Form1.Show(); 
} 

MyProject.Formsは、生成でプロパティですMyProjectクラス、タイプMyFormsです。あなたがこのダイビングを始めると、そこにかなりの量のコードが生成されます。

C#これはもちろん、すべてを行いますが、通常はあなたの背中の背中と同じくらいの歴史がありません。これは、匿名型、イテレータブロック、ラムダ式などのようなもののための追加のメソッドと型を構築しますが、VBがここで行うのと全く同じ方法ではありません。 C#が構築するすべてのコードは、あなたが書いたソースコードに対応しています。

もちろん両方のアプローチについて議論があります。個人的に私はC#のアプローチを好むが、それはおそらく驚きではない。私はなぜそれがシングルトンだったかのようにフォームのインスタンスにアクセスする方法があるはずではないがフォームの場合は言語がGUIを使用しているかどうかと同じように動作するようにクラスや何か、基本的に。

+0

Form1.Show()がエラーを生成しています。 '' WindowsApplication2.Form1 'は、デフォルトインスタンスを通じて自分自身を参照することはできません。代わりに '私'を使用してください。 –

+3

@ Javed:おそらく私は私の例のように、あなたは別のクラスからそれを使用していないでしょう。 –

関連する問題