2014年10月13日 (月)

Express Editionだと例外時の表示が違う

いままでも「あれ?」とは思っていたんですが、今日じっくり見てみてはっきり違いを意識しました。

Visual Studioでプログラムを実行していて例外が発生すると、例外処理アシスタントというものが表示されて例外の種類やメッセージ、参考のリンクなどを表示してくれます。例外処理アシスタントは例外処理ヘルパーとも呼ばれます。

この機能は2005から追加されました。この表示をクリックしてさらに例外の詳細を確認することもできます。

今日気が付いたのはVisual Studio 2010のExpress Editionではこの機能が利用できるのですが、2012と2013のExress Editionでは利用できないということです。代わりに簡単なダイアログが表示されます。

私はVBで確認したので他のExpress Editionでは状況が違う可能性はあります。2010では同じだったものをなぜわざわざ変えたのか疑問です。どこか設定を変えれば例外処理アシスタントを利用できるのでしょうか。ちょっと見た感じではそれらしい設定はありませんでした。

開発環境の設定を「全般」にリセットすればよいのかもしれませんがExpress EditionではGUIからはこの変更ができないし、あまり標準的でない設定にするのも嫌です。ちょっと気に入らないですがこのまま使い続けることになりそうです。

| | コメント (0) | トラックバック (0)

2014年2月24日 (月)

SignalR で OWIN Startup クラスがない!

サーバーから直接クライアントのJavaScriptを呼び出せる(かのように動作する)SignalRという技術を試してみました。

少し前からあった技術ですが私は初めての体験です。

このサイトを参考にして、Visual Studio 2013のVisual Basicでやってみました。

http://www.asp.net/signalr/overview/signalr-20/getting-started-with-signalr-20/tutorial-getting-started-with-signalr-20

ところが途中の手順に「OWIN Startup Class」を追加するというのがあるのですが、私の環境では新規追加の一覧にこれがありません。10分くらい試行錯誤して気が付いたのですが、何とC#でプロジェクトを作成するとちゃんと「OWIN Startup クラス」というものが一覧にあるのに、VBでは存在しないではありませんか。

理由はともかく、そのような事情が分かればあとはすっぱりあきらめて空のクラスに自分でOWIN Startup クラス相当のプログラムを書くだけです。

同じところでつまづいている人のために、ここにVB版のOWIN Startup クラスを載せておきます。

Imports Microsoft.Owin
Imports Owin
<Assembly: OwinStartup(GetType(Startup))>

Public Class Startup
    Public Sub Configuration(app As IAppBuilder)
        'アプリケーションの設定方法の詳細については、http://go.microsoft.com/fwlink/?LinkID=316888 を参照してください
        app.MapSignalR() 'このサンプル以外の場合、この行は不要な場合があります。
    End Sub
End Class

このあと、なんとかSignalRの簡単なサンプルを作成できました。わかってみれば簡単に使えて良さそうですが、はじめてだと勘所がわからずに少し時間がかかりそうです。

せっかくなので、完成版のプログラムをここに載せておきます。

このプログラムを実行すると、サーバー側のServerHelloメソッドが呼び出されます。ServerHelloメソッドはクライアント側のClientHelloメソッドを呼び出します。ClientHelloメソッドはalertで画面にサーバーから受信したメッセージを表示します。

プロジェクト構成

Webアプリケーションで Emptyのテンプレートに Webフォーム 機能を追加したものを基にしました。

Capture01

▼HelloHub.vb

Option Strict Off

Imports Microsoft.AspNet.SignalR

Public Class HelloHub
    Inherits Hub

    Public Sub ServerHello(text As String)
        Clients.All.ClientHello("Hello, " & text)
    End Sub

End Class

▼HtmlPage1.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>
</head>
<body>
    <h1>SignalR Test</h1>
    <script src="Scripts/jquery-1.10.2.min.js"></script>
    <script src="Scripts/jquery.signalR-2.0.1.min.js"></script>
    <script src="signalr/hubs"></script>
    <script>
        $(function () {

            var hub = $.connection.helloHub;

            hub.client.ClientHello = function (text) {
                alert(text);
            };

            $.connection.hub.start().done(function () {
                hub.server.serverHello("Visual Basic 中学校");
            });
        });
    </script>

</body>
</html>

▼startup.vb

※上掲のVB版OWIN Startup クラスと同じです。

▼その他

その他のファイルはまったく編集する必要はありません。

| | コメント (2) | トラックバック (0)

2013年6月 4日 (火)

Visual Studio 2013情報がでてきました

次期Visual Studioである Visual Studio 2013 の情報が出始めました。

この英語のブログが詳しいです。

http://blogs.msdn.com/b/bharry/archive/2013/06/03/visual-studio-2013.aspx

現在公開されている情報は、チーム開発機能(Team Foundation Server)の強化がほとんどで言語機能の強化など趣味・個人のユーザーにはあまり関係しないような内容です。

ざっとあげると以下のようです。(私の英語誤読があるかもしれません。というか大変なのであまりよく読んでいません・・・)

■コーディング機能

・ヘッズアップディスプレイ

   コードの上に吹き出しのようにいろいろな情報が表示されます。

    ・メソッドのリファレンス

    ・単体テストの状況

    ・変更履歴

私は単体テストの状況が見やすくなるのがいいなと思います。

■チーム開発向け機能

・アジャイル開発管理機能の強化

・バージョン管理機能の強化

・チームエクスプローラーが刷新されて見やすくなった。

・このソースコードレビュー画面はクール

http://blogs.msdn.com/cfs-filesystemfile.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-36-52-metablogapi/0435.image_5F00_75380750.png

■その他

| | コメント (1) | トラックバック (0)

2013年5月26日 (日)

自分自身を再定義するラムダ式

ラムダ式の導入でVBでも関数型言語のようなプログラミングをやろうと思えば真似できるようになってきました。

たとえば、最初に関数(メソッド)が呼び出されるときに、その関数が自分自身をよりシンプルに再定義することができます。

例として、管理者と一般ユーザーとで同じ関数を呼び出しても処理内容が違う場合を考えてみましょう。

普通のVBの発想ではIf文で切り分けるか、管理者と一般ユーザーをそもそも別クラスにしておくという構成をとると思います。関数が自分自身を再定義することで次のようにも書くことができるようになります。

Public Class Form1

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Me.DoAnything()
    End Sub

    Public DoAnything As Action =
        Sub()
            If IsAdministrator() Then
                Me.DoAnything =
                    Sub()
                      '管理者用の処理
                        MsgBox("管理者権限の場合の処理")
                    End Sub
            Else
                Me.DoAnything =
                    Sub()
                        '一般ユーザーの場合の処理
                        MsgBox("一般ユーザーの場合の処理")
                    End Sub
            End If

            Me.DoAnything()

        End Sub

    Public Function IsAdministrator() As Boolean
        '省略
        MsgBox("権限を調べます。")
    End Function

End Class

これを実行すると、最初は

「権限を調べます。」

「一般ユーザーの場合の処理」

と表示されますが、2回目以降は「一般ユーザーの場合の処理」とだけ表示され、権限をもう一度調べることをしません。最初の時点で一般ユーザーであることがわかっているので2回目以降は無駄なことをしないような構造になっています。

しかし、見てわかるようにプログラムがとても難しく感じられます。このケースでは普通にIf文かクラスを分ける方がよいでしょう。

ここでは、こんなこともできるという例として紹介しました。この発想をもっと有効に役立てられるシーンがあるかもしれません。ないかもしれません。今のところは思いつきません。

| | コメント (0) | トラックバック (0)

2013年5月11日 (土)

IsNothingと Is Nothingの違い

変数がNothingであるか調べるにはIsNothing関数の戻り値を見る方法と、 Is Nothing 使って調べる方法の2つがあります。

Dim s As String

'お勧めの方法
If s Is Nothing Then
    '省略
End If

'お勧めではない方法
If IsNothing(s) Then
    '省略
End If

Is Nothing の方が少し動作が速いのでこちらを使うべきです。

両者にはもう1つ違いがあります。

IsNothing関数は値型の変数に対しても使えるのに対し、Is Nothingは値型の変数に対して使用するとビルドエラーになります。

けれど値型の変数がNothingであるか調べたくなる場合は皆無といってよく、この違いは無視できます。多分、この余計な機能がついている分IsNothingの方が遅いのでしょう。

念のために補足しておくと値型の変数をNothingにすることはできず、値型の変数に対するIsNothing関数は常にFalseを返します。

Dim i As Integer = Nothing 

のようなプログラムは一見Nothingを代入しているように見えますが、実は初期値である0を代入しています。(だからこの例のプログラムは意味がありません。)

| | コメント (0) | トラックバック (0)

2013年4月20日 (土)

最適化パレットでgifを保存

bmpなどの画像をgifとして保存するときに、Windows付属のペイントだと画質が悪くなってしまいます。ペイント以外のソフトでもこうなることが多いようです。高級なソフトではきれいに保存できるものもあります。

もともとgifは256色しか表現できないので仕方ない場合もありますが、そんなにたくさん色を使っていない場合でも画質が悪くなってしまうので残念です。

でも、高級なソフトを用意しなくても私たちプログラマは自分でプログラムを作るという手があります。

私が作ったプログラムはこんな感じです。このプログラムを試す場合はWPFプロジェクトとして作成するのがよいです。Windows フォーム アプリケーションやWeb フォーム アプリケーションなどでも参照設定を追加すれば可能です。

Dim sourceFileName As String = "C:\vb\test.bmp"
Dim gifFileName As String = "C:\vb\savegif.gif"

Dim bmpImage As New BitmapImage(New Uri(sourceFileName))
Dim gifEncoder As New GifBitmapEncoder
gifEncoder.Frames.Add(BitmapFrame.Create(bmpImage))

Using stream As New IO.FileStream(gifFileName, IO.FileMode.Create)
    gifEncoder.Save(stream)
End Using

これでtest.bmpがsavegif.gifという名前で保存されます。

| | コメント (0) | トラックバック (0)

2012年6月 9日 (土)

Visual Studio Express 2012のデスクトップアプリケーション

Visual Basic 2012を搭載しているVisual Studio 2012のRC版がリリースされています。RC版はまだ正式版ではありませんが問題がなければこのままリリースする予定のリリース候補版という意味です。

このRC版のExpress EditionのラインナップがWebアプリケーション作成用のExpress for Webとメトロアプリケーション作成用のExpress for Windows8しかなく、従来広く使用されていたWindowsフォームアプリケーションやコンソールアプリケーションなどのいわゆるデスクトップアプリケーションがExpress Editionでは作成できなくなってしまうという話がWebで公開されていました。

http://www.atmarkit.co.jp/fdotnet/chushin/opinion_desktopapp/opinion_desktopapp.html

実際RC版のダウンロードサイトでもExpress版にはこれらのアプリケーションが作成可能なものが公開されておらず、私はとても残念な気持ちとともに大分やきもきしてしていたのですが朗報が入ったので久々にブログをアップします。

現時点(6月9日)ではWindowsフォームアプリケーションやコンソールアプリケーションが作成可能なExpress for Desktopがリリースされるという情報が公開されています。

http://blogs.msdn.com/b/visualstudio/archive/2012/06/08/visual-studio-express-2012-for-windows-desktop.aspx

よかった…。

Express Editionでデスクトップアプリケーションが作成できないようにするというのはマイクロソフトが従来型のデスクトップからメトロ型のデスクトップへのパラダイムシフトを遂げる上の大きな賭けだと思います。ただ、この賭けに敗れた場合マイクロソフトの傷はかなり深くなっていたはずです。

今回デスクトップアプリケーションが作成可能なExpress Editionの投入がアナウンスされたことでマイクロソフトは大きな賭けに出ることはせず軟着陸によってパラダイムシフトを目指すということを意味していると私は思っています。

RC版は誰でも無償でダウンロードできます。現時点ではまだExpress for Desktopは公開されていません。

http://www.microsoft.com/visualstudio/11/ja-jp/downloads#groups

| | コメント (0) | トラックバック (0)

2011年5月15日 (日)

Split考

■2つのSplit

文字列を区切ってくれる便利なSplitメソッドには実は2種類あって、1つがStrings.Split, もう1つがString.Splitです。(紛らわしいですがスペル的にはStringが複数形か単数形かの違いです。)

VBではStringsモジュールは省略可能なので、Strings.Splitを使っている人は普段は単にSplitと書いていて、Stringsモジュールを使っていることを意識していないことと思います。

それぞれの例

Strings.Splitの例

Dim value As String = "A,B,C"
Dim items() As String = Split(value, ",")

String.Splitメソッドの例

Dim value As String = "A,B,C"
Dim items() As String = value.Split(",")

■それぞれの違い

で、このどちらを使うかですが、昔何か面倒なことがあって私はずっとStrings.Splitの方を使っています。

ところが時が経つにつれて「何か面倒なこと」の内容を忘れてしまい、最近は「何でこっちがいいんだったろうか?」などと思いながらプログラムする日々が続いていました。

それを久しぶりに思い出したのでブログに書いておきます。知っている人にはつまらない話だと思います。

実はString.Splitはそのままでは区切り文字を1文字しか指定できないのに対し、Strings.Splitの方は何文字でも指定でき、区切り文字が2文字以上の時の書き方に差が出るのです。

どういうことかというと、

まず、Strings.Splitで区切り文字が2文字の場合、

Dim value As String = "AXYBXYC"
Dim items() As String = Split(value, "XY")

これは結果は "A", "B", "C"になります。

ところが、

同じことをそのままString.Splitで書くと、

Dim value As String = "AXYBXYC"
Dim items() As String = value.Split("XY")

これの結果は "A", "YB", "YC"になります。

String.Splitの方でこのような書き方をすると先頭の1文字だけ(上の例だと"X"だけ)を区切り文字として扱い、2文字目以降は無視されるのです。

■違いの理由

これは、上記のString.Splitの第1引数はChar型であって、String型でないことによります。"XY"はString型なので、上のような呼び出しを行うとChar型に自動的に変換されます。ところがChar型は1文字しか表せない方なので"X"だけが採用されるのです。

String.Splitを使って複数文字の区切り文字を扱いたい場合、文字列型ではなく、文字列型の配列にするとうまくいきます。

次のように書きます。

Dim value As String = "AXYBXYC"
Dim items() As String = value.Split({"XY"}, StringSplitOptions.None)

多分、これが面倒で統一的な書き方ができるStrings.Splitを私は使い続けていたのでしょう。

なお、Option Strict Onの状態ではvalue.Split("XY")はそもそもエラーになって実行できません。

■補足

ついでに念のため補足。Option Strict Onの状態だとこれもエラーにされます。

Dim items() As String = value.Split(",")

これを解決する一番簡単な方法は次のように書くことです。

Dim items() As String= value.Split(","c)

| | コメント (1) | トラックバック (0)

2011年5月 8日 (日)

さようなら、ByVal

2011年3月にVisual Studio 2010 SP1では、いくつかの機能追加と変更、バグの修正が行われています。

http://support.microsoft.com/kb/983509/ja

この中で、見落としていたのですがVBでプロシージャを作ると自動的にパラメーターの前につくByValが自動ではつかなくなったのをご存じだったでしょうか?

私は最近気が付きました。

■具体例

たとえば、

private sub test (x as integer)

と書いて、[Enter]キーを押すと、従来は次のようにXの前にByValが自動的に付きました。

Private Sub test(ByVal x As Integer)

それがSP1を入れると大文字小文字が変換される以外特に変化なしです。

Private Sub test(x As Integer)

xの前に何も書かなかった場合、ByValと同じ意味になりますので機能上の変更はないです。

イベントプロシージャでも変わりました。フォームをダブルクリックすると従来は次のコードが生成されていました。

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

SP1を入れるとこうなります。

Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load

■変更の背景

このことは上にあげたリンク先の変更点の一覧にも書いてあります。

さらにそこからリンクをたどっていくともとはユーザーからの提案だったようです。

https://connect.microsoft.com/VisualStudio/feedback/details/542271#details

引用

>At this point, repeating ByVal everywhere is just noise.

私訳:こうやって見ると、どこにでもいちいちByValってでるのはうざいです。

■Visual Basic 開発チームへの提案は誰でもできる

日本語でも提案をすることはできますので、普段思っていることがある方は提案してくださいね。(VB中学校よりもレベルは高いので、「こんなこと提案していいのかな」と思ったらまずはVB中学校掲示板で相談してみて下さい。)

マイクロソフトへの提案サイト(日本語版。バグ報告もあり。)

https://connect.microsoft.com/VisualStudioJapan/Feedback

Visual Basic中学校掲示板

http://rucio.cloudapp.net/ThreadList.aspx

| | コメント (0) | トラックバック (0)

2011年4月 3日 (日)

例外が発生してもデバッグで停止しない現象

今まで気が付きませんでしたが、例外が発生してもデバッガが停止してくれないというバグがVisual Studioにはあったのです。

64ビット版のWindowsで開発していると、FormのLoadイベント実行中に例外が発生しても実行が停止せず、フォームが表示されます。

たとえば次のコードで再現できます。

Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim i As Integer = CInt("ASDF")
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim i As Integer = CInt("ASDF")
    End Sub
End Class

このコード、どうみてもFormのLoadイベントで型変換エラー(InvalidCastException)が発生するはずなのですが、見事にスルーされ、普通にフォームが表示されます。Button1をクリックした場合は期待通り例外が発生し、デバッガにより処理が中断されます。

実はどちらの場合も例外自体は発生しているようなのですが、その行で黄色く表示されて処理を停止するという部分がうまく動かないようです。

なお、Loadイベントで例外発生行より下にコードがある場合、それらのコードは実行されません。

ためにしVisual Studio 2010 SP1を入れてみたんですが、この現象は直っていませんでした…。こまりますねぇ。

■対象1:Shownイベント

お手軽に対処するにはLoadイベントではなくShownイベントを使うという手があります。Shownイベントではこの現象は発生しません。ただ、LoadとShownは発生するタイミングが違うので代替できない場合もあります。

■対処法2:Stop

他には、Stopを使った停止は可能なので、このようなプログラムを書くことでかわせる場合もあるでしょう。

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        On Error Resume Next

        Dim i As Integer = CInt("ASDF")

        If Err.Number <> 0 Then
            Stop
        End If
    End Sub

■対処法3:例外発生時に停止

あと、Expressでは使えない手ですが、[デバッグ] メニュー- [例外]の設定で、Common Language Runtime Exceptions の「スローされるとき」にチェックをするという方法もあります。こうするとLoadイベント実行中の例外でも停止してくれるようになりますが、他のTryとかOn Errorとかやっているところでも例外発生時にいちいち停止するようになってしまうので、万能ではありません。

Loadeventbug

参考

http://blogs.msdn.com/b/debugger/archive/2010/05/12/visual-studio-debugger-fails-to-catch-unhandled-exception-for-a-windows-form-or-wpf-application.aspx

| | コメント (0) | トラックバック (0)