次の方法で共有


C#とVB.netの違い

質問

2008年3月27日木曜日 2:26

お世話になります。
当方、C#とVB.netを少しずつかじった事がある程度の者です。
こちらで質問してよいのか分かりませんが、C#とVB.netの違いについて教えて頂きたいです。

C#とVBについて「C#はオブジェクト指向だけど、VBはオブジェクト指向でない」とか、
「VBよりC#の方が動作の速いプログラムが組める」という話を聞くのですが、
VB.netには継承やインターフェース・デリゲート・イベント等の機能があり、
そこまでC#に劣っているか?という疑問があります。
(.NET環境では無いVB6.0等ではオブジェクト指向が難しいのは承知しております)
C#を使おうとVB.netを使おうと、結局は使う人間によって、オブジェクト指向になったりならなかったりだと思うのですが。。
C#とVB.netで何か決定的に違う部分がありましたら教えて頂けませんでしょうか?
宜しくお願い致します。

すべての返信 (13)

2008年3月27日木曜日 3:49 ✅回答済み

 茂樹 さんからの引用
C#とVBについて「C#はオブジェクト指向だけど、VBはオブジェクト指向でない」とか、
「VBよりC#の方が動作の速いプログラムが組める」という話を聞くのですが、
VB.netには継承やインターフェース・デリゲート・イベント等の機能があり、
そこまでC#に劣っているか?という疑問があります。

 

茂樹さんが考えているとおりで、まったくのデマです。 この業界では 「VB を上から目線で見ないとダサい」 「Windows より Linux」 と言った方がカッコイイと思っている方が多いように感じます。 ライフハック(笑) みたいなものだと思っています。(言いすぎ?)

C#を使おうとVB.netを使おうと、結局は使う人間によって、オブジェクト指向になったりならなかったりだと思うのですが。。

 

まったくそのとおりだと思います。 主としているプログラミング言語によって OOP にならない可能性があるという 「傾向」 は否定しません。

 

C#とVB.netで何か決定的に違う部分がありましたら教えて頂けませんでしょうか?

 

昔、少しまとめたことがあります。

言語仕様レベルでは少々の違いでしかないと思います。


2008年3月27日木曜日 5:10 ✅回答済み

少し補足しますと、C#もVBも必ずクラスを必要としますから、OOP言語です。どんなにおかしなクラスの設計や使い方をしようとも、それはセマンティクスの問題であり(ロジックが正しい意味をもつかかどうかという問題)、プログラムの枠組みはOOPとして動きます。セマンティクス的に、それはOOPじゃないよという議論はあると思いますが。


2008年3月27日木曜日 5:32 ✅回答済み

外池と申します。私もVBとC#の比較に興味を持っているのですが、いくつかコメントさせてください。

 

まず、オブジェクト指向に関しては、VBとC#はまったく同等と私は考えています。他の方と同じ意見です。

 

次に、C#の方が速いプログラムを書ける、ということに関してはその通りだと思います。ご存知かと思いますが、C#にはアンセーフというオプションがあって、ポインターを使ったプログラムが書けますので、この場合、確かに速くなります。ただ、その速くなる度合いは、それほど大したものではありません。(個人的には、「なんだ、その程度しか速くならないのか」という程度)

 

C#の言語体系はシンプルで、.Net FrameworkのSystem名前空間に異存する部分が大きいような印象を持ちます。.Net Frameworkに純粋に染まっていくなら、C#が良いように思われます。

 

一方、VBも言語体系はシンプルですが、.Net Frameworkに、VisualBasic名前空間が用意されていて、最近、特にこのクラスライブラリーの機能が増えてきているようです。.Net Frameworkに純粋に染まっていくことに比べて、VisualBasic名前空間を使うことは邪道と感じてしまうこともあるのですが、しかし、上手く使いこなせれば、非常に便利なことも事実です。

 

私の結論として、好みと用途にも依る選択以上の優劣はないと思います。

 


2008年3月27日木曜日 5:54 ✅回答済み

 外池 さんからの引用

次に、C#の方が速いプログラムを書ける、ということに関してはその通りだと思います。ご存知かと思いますが、C#にはアンセーフというオプションがあって、ポインターを使ったプログラムが書けますので、この場合、確かに速くなります。ただ、その速くなる度合いは、それほど大したものではありません。(個人的には、「なんだ、その程度しか速くならないのか」という程度)

 

VBプログラマーの私の印象では、ポインタは早いです。(^^)

640*480の5*5とかのカーネルを張った画像処理が何秒から何秒になる、とか提示できれば

客観的な議論ができるのですが、今、そのデータを持っていません。

私としてはポインタは手放せません。

重たいループはすべてC#でポインタにします。

(VB6のときはCでWin32DLLを使っていた。)

NETはプロジェクトの連携も簡単ですからね。

 

私も好みで決めていいと思いますし、VBを使うと決めたら全部VBにしなくては

ならないということでもない、と思います。


2008年3月27日木曜日 6:33 ✅回答済み

外池です。うーむ。私もVBプログラマなのですが・・・ (^^ゞ

 

プログラムの書き方にも依るんでしょうねぇ。>ポインターで速くなるかどうか

 

ポインターに[]をつけて、境界チェックをはずしただけの配列風の使い方だと、私の印象ではあまり速くならないように思うのです。アンマネージコードのデバッグができる状態で、逆アセンブルを見てみたのですが、通常の配列を使った場合の境界チェックも、比較文がひとつ入るだけのようで・・・。FFTをもともとVBで書いていたのですが、C#にしてみたところ・・・、2割程度速くなったかな?

 

ポインターそのものをインクリメントしたり、デクリメントして操作をしていく場合は、これは、速いですね。

 

 

 


2008年3月27日木曜日 6:40 ✅回答済み

 trapemiya さんからの引用
少し補足しますと、C#もVBも必ずクラスを必要としますから、OOP言語です。

 

明確な定義はありませんが一般的な定義で言えば、クラスというより独自の型 (Object) が扱えれば 「オブジェクト指向言語」 として良いとなっています。 ただ 「VB がオブジェクト指向言語か?」 と 「VB で作成したブツはオブジェクト指向プログラミングと言えるか?」 は意味合いが異なります。 質問者さんは後者を質問されていると私は捕えました。

ちなみに VB6 も独自の型が定義できるのですから、オブジェクト指向言語を名乗る資格はあると思います。 よく分類上は非/手続き型だとか言われていますけど。(Wikipedia の説明の方は個人的にはしっくりきますね)


2008年3月27日木曜日 6:42 ✅回答済み

 外池 さんからの引用

外池です。うーむ。私もVBプログラマなのですが・・・ (^^ゞ

 

プログラムの書き方にも依るんでしょうねぇ。>ポインターで速くなるかどうか

 

ポインターに[]をつけて、境界チェックをはずしただけの配列風の使い方だと、私の印象ではあまり速くならないように思うのです。アンマネージコードのデバッグができる状態で、逆アセンブルを見てみたのですが、通常の配列を使った場合の境界チェックも、比較文がひとつ入るだけのようで・・・。FFTをもともとVBで書いていたのですが、C#にしてみたところ・・・、2割程度速くなったかな?

 

ポインターそのものをインクリメントしたり、デクリメントして操作をしていく場合は、これは、速いですね。

 

VB同盟でも作りましょうか。ww

 

私のポインタの使い方はこんな感じです。

 

for(i=0;i<Width;i++,p+=4)

{

*(p+0)=*(p+0)+ほにゃらら

*(p+1)=*(p+1)+ほにゃらら

}

 

VBからC#に渡す段階では配列で渡し、fixedでポインターにしています。


2008年3月27日木曜日 6:44 ✅回答済み

 茂樹さんこんにちは

 もう納得されちゃったみたいですが、私にも言わせてください。

 

 オブジェクト指向の機能としては、VBが劣っているとは思いません。

 オブジェクト指向以外の機能で、C#にYieldと匿名メソッドがあるのは決定的な違いだと思います。

 Yieldがあるためにアーキテクチャパターンの一つPipe & Filterパターンが書きやすくなります。Pipe & FilterパターンについてはVB2008からは標準クエリ演算子やLINQを経由して使用することになります。

 匿名メソッドがあるとクラスが不要になったりします。VB2008では戻り値を一つの式で書ける単純なFunctionはラムダ式が使えますが、複文やSubはラムダ式が使えません。C#ではそのような制限がありません。匿名メソッドの代わりにクラスを使うと大変見にくくコーディング量の多いものになる場合があります。特にAdapterパターン。

 私の場合はこの2点の違いがあることによりVBからC#に移行することも考えています。特に匿名メソッド(ラムダ式)があることは重視しています。以下のページにラムダ式を使ったサンプルを載せています。

 

http://www.mahoroba.ne.jp/~mw_ken/lambdaform.html


2008年3月27日木曜日 5:15

じゃんぬねっと様

素早い返答有難う御座います。
HP拝見させて頂きました。
VBしか使った事が無い人はオブジェクト指向が苦手、というイメージはありますが、
言語仕様としては、世間で言われるほど両者に違いは無いのですね。
大変参考になるご意見、有難う御座いました。


2008年3月27日木曜日 5:22

trapemiya様

ご回答有難う御座います。
仰るとおり、VBはそもそもオブジェクト指向言語なのですよね。
参考になりました。
有難う御座います。


2008年3月27日木曜日 8:37

皆様色々なご回答有難う御座います。
正直、こんなに反響があるとは思っていませんでした。
非常に参考になります。

外池様
はなはなはな様

ご意見有難う御座います。
動作速度に関して、アンセーフモードがあるのは大きな違いですね(使った事が無かったので思い浮かびませんでした^^;)
むやみに使うべきものでは無いのでしょうが、動作速度が求められる場面での選択肢が1つ多いというだけで
VBに対して大きなアドバンテージかも知れません。
アンセーフモードの動作速度検証が行われている記事がありましたのでご参考までにURLを下記に記載します。
この記事によりますと、ビットマップを読み込んでネガ反転を行う処理にかかった時間が、
セーフモードだと21秒で、アンセーフモードだと0.5秒だそうです。
(記事にもあるように、ネガ反転のやり方で両者の処理時間は変わってくると思います。あくまでご参考までに。)

http://www.atmarkit.co.jp/fdotnet/csharp_abc/csharp_abc_021/csharp_abc05.html

じゃんぬねっと様

質問がややこしくなってしまってすみません^^;
「VB がオブジェクト指向言語か?」 と 「VB で作成したブツはオブジェクト指向プログラミングと言えるか?」
を切り分けて考える事が出来ていませんでしたが、
ニュアンスとしてはじゃんぬねっと様が仰るとおり、後者の方に近いです。
巷では(私の周りだけかも知れませんが^^;)
「VBではオブジェクト指向のプログラミングができない」という風に聞こえる意見を耳にするもので。。

三輪の牛様

仰るとおり、匿名メソッドは非常に使い勝手の良いものですね。
Yieldについては知りませんでした^^;
確かに便利だと思います。
参考になりました^^


2008年3月27日木曜日 9:18

外池です。すいません、細かいことですが、誤解がないように補足させてください。

 

http://www.atmarkit.co.jp/fdotnet/csharp_abc/csharp_abc_021/csharp_abc05.html

に紹介のある例から、セーフモードだと21秒、アンセーフモードだと0.5秒を直接比較するのは、マズイかと思います。

 

Bitmap画像の画素の操作において、1)SetPixelやGetPixelメソッドを使うことと、2)Bitmap画像の生情報をマネージ(セーフ)なByte配列で取り出して3)さらに、アンセーフなポインターで操作することと、

 

1)と、2)+3)の効果を比較していることになっているので、アンセーフモードが速いという結論には直結しません。

 

ほぼ同じことについて、他のスレッドで話題が出ていましたが、1)が遅いのであって、セーフモードの2)のレベルでプログラムすれば、相当に速くなるようです。

 

 

 


2008年3月27日木曜日 10:10

サンプル書いて見ました。

ちょっとしか早くならないですね。

 

Code Snippet

private void button1_Click(object sender, EventArgs e)
        {
            DateTime st;
            DateTime et;
            TimeSpan ts;

            int[] bTest;
            int l=5000*5000*4;

            bTest = new int[l];

            st = DateTime.Now;

            int i;
            for (i = 0; i < l; i++)
            {
                bTest[i] = bTest[i] + 1;
            }

            et = DateTime.Now;
            ts = et - st;
            MessageBox.Show(ts.ToString());
            bTest=null;
            GC.Collect();

        }

        unsafe private void button2_Click(object sender, EventArgs e)
        {
            DateTime st;
            DateTime et;
            TimeSpan ts;

            int[] bTest;
            int l = 5000 * 5000 * 4;

            bTest = new int[l];

            st = DateTime.Now;

            int i;

            fixed(int* ptrtest = &bTest[0])

            {

                int* ptr = ptrtest;
                for (i = 0; i < l; i++,ptr++)
                {
                    *ptr = *ptr + 1;
                }

                et = DateTime.Now;
                ts = et - st;
                MessageBox.Show(ts.ToString());
            }
                 bTest=null;
                 GC.Collect();

        }