痛い一日を過ごす

VisualStudio2008からVisualSourceSafeにファイルをチェックインしたいのだが、なぜかうまくいかない。

うまくいかないというか、ずっとチェックアウトされっぱなしになってしまう。

おかしいなー。

と、そういえばF#いれたし、もしかしたら開発環境壊れたかなー。とか思って、VisualStudio2008を再インストールしたりしてみたんだけど、直らない。

おかしいなー。チェックアウトされっぱなしだなー。

と悩んでいたところで、

「チェックアウトされっぱなし?」

と気づいて、チェックインするときのダイアログのオプションを見たら

「チェックアウト状態を保持する。」

にチェックが入っていたのでした・・・。

これは痛い一日を過ごした。

Share
カテゴリー: .NET

匿名型と匿名メソッド・ラムダ式に見るVBとC#の違い

匿名型

VBの場合

・keyキーワードを設定したプロパティのみEquals,HashCode生成時の対象プロパティとなる

・keyキーワードを設定したプロパティの値の代入は初期化時のみ

・keyキーワードが設定されていないプロパティは後から値の代入が可能

C#の場合

・後から値の代入が不可能

・全てのプロパティがVBでいうところのkeyキーワードを設定した状態となっている

匿名メソッド・ラムダ式

VBの場合

・式のみ実装可能

・コードブロックの実装は不可なので通常のメソッドを実装するようにはできない

C#の場合

・式の実装もコードブロックの実装も可能なので通常のメソッドを実装するのと同じだけの事が可能

匿名型を利用して複数の自動変数の関連付けをしたい時があって、そんなときはVBの仕様が嬉しい。

その半面、メソッドアウトしたいがスコープは元のメソッド内に留めたい時があって、そんなときはC#の仕様が嬉しい。

Share
カテゴリー: .NET

「日本ユニシス、.NET Framework 1.1/3.5移行ホワイトペーパーを無償公開」というわけで・・・

日本ユニシス株式会社は9月9日、.NET Framework 1.1環境から最新版の.NET Framework 3.5への移行方法をアプリケーション構築の観点から検証したホワイトペーパーを公開すると発表した。同日より同社サイトにおいて無償で公開する。

日本ユニシス、.NET Framework 1.1/3.5移行ホワイトペーパーを無償公開

読んでみたんだけど、VisualStudio2005以降はTransactionScopeを利用した自動トランザクション前提というところにちょっと違和感を感じた。

もう、みんな自動トランザクションしか使っていないのかな?

仕事でTransactionScopeを利用したことが今のところまだ無い。

Share
カテゴリー: .NET

アセンブリから特定の型を継承したクラスのメタデータを取得する方法

アセンブリから特定の型を継承したクラスのメタデータを取得したい時は、System.Type型のIsSubclassOfメソッドを利用します。

以下のように使います。

Assembly assemblyObject = Assembly.LoadFile(対象ファイル名);
foreach(System.Type targetType in assemblyObject.GetTypes().Where(x => x.IsSubclassOf(typeof(継承元のクラス))).ToList())
{
Console.WriteLine(targetType.Name);
}
Share

アセンブリから特定のインタフェースを実装したクラスのメタデータを取得する方法

アセンブリから特定のインタフェースを実装したクラスのメタデータを取得したい時は、System.Type型のGetInterfaceメソッドを利用します。

Assembly assemblyObject = Assembly.LoadFile(対象ファイル名);
foreach (System.Type targetType in assemblyObject.GetTypes().Where(x => x.GetInterface("インタフェース名") != null).ToList())
{
Console.WriteLine(targetType.Name);
}
Share

WCFを利用するためのコードジェネレータがやっとできた

最近、こつこつと汎用でありながらインテリセンスが有効になるようにこだわったデータ検索とデータ更新のクラスを作成したが、

(MakeGenericTypeが無かったらもうちょっと大変だった。)

今日はそれを利用した簡単なメンテナンスデータアクセス向けサービスのクラス群を自動生成するツールがやっとできた。

コードジェネレータは難しくないけど、力業だと思った次第。

これで、簡単なデータメンテナンスサービスや検索サービスについては、自動生成で対応できる。

クライアントを実装するときもちゃんと項目名がインテリセンスで出てくるように作ってあるから項目名のミスもないだろうし。

インタフェースは具象だからWCFテストクライアントでテストできるので楽ちん。

あとは認証部分のお勉強。

Share
カテゴリー: .NET

Generic型を動的に生成する方法

WCFを利用したサービスのバックグラウンドで動いてもらうフレームワークを作成するときに必要だったので調べてみると、System.Type型のメソッドにMakeGenricTypeという、そのままのメソッドがあってこれで作成できる事がわかりました。

そこで、ここではList<int>型を作成し、1から10までの値をListに登録するサンプルコードを紹介したいと思います。

普段の実装でこのようなコメントを書くことはありませんがコメントで解説します。

    //List<>の<>内に入れる型のメタデータの配列を生成します。
    //今回はList<int>型を作成したいので、int型のメタデータを生成します。
    System.Type[] genericsTypeArguments = { typeof(int) };

    //List<>のメタデータのMakeGenricTypeメソッドに先ほど作成した
    //int型のメタデータを渡すことでList<int>型のメタデータを作成できます。
    //実は、これを知るまで<>という中に何も入れない書き方ができる事を知りませんでした。
    System.Type integerListType = typeof(List<>).MakeGenericType(genericsTypeArguments);

    //後は通常のメタデータからインスタンスを生成するように
    //CreateInstanceでインスタンスを生成します。
    var integerList = Activator.CreateInstance(integerListType);

    //integerListはobject型であり、動的に作成するというシナリオ上、
    //何のListになったのかわからないので、
    //ListのAddメソッドの情報を取得します。
    var addMethodInfo = integerListType.GetMethod(&quot;Add&quot;);

    //addメソッドを利用するサンプルとして便宜的に1から10までの数と登録します。
    foreach (var value in Enumerable.Range(1,10))
    {
        //Addメソッドの情報からInvokeメソッドを利用して、
        //Addメソッドを実行し、与えられた値を設定します。
        addMethodInfo.Invoke(integerList, new object[] { value });
    }

以上が、ジェネリック型を動的に生成する方法です。

型の配列の要素を現在のジェネリック型定義の型パラメータで置き換え、結果の構築型を表す Type オブジェクトを返します。

Type.MakeGenericType メソッド (System)

Share

Singleメソッドを使うことで単一の要素を返せる事を知った

LINQを使って書くときに結果が必ず1件になることが分かっているのに今まで

var test = Enumerable.Range(1,10).Where(x => x == 5).Select(x => x);
Console.Write(test[0]);

とSelectメソッドを利用した上で、配列としてアクセスしていたが、MSDNを見て(というかインテリセンスでそれっぽいのを見つけてMSDNにアクセスして確認して)いたらSingleメソッドというものを見つけた。

どうも要素が一つに限定される場合はSelectの代わりにSingleメソッドを利用する事で「要素が一つの配列」としてではなく、単一の要素とする結果になるらしい。

という事で、

var test = Enumerable.Range(1,10).Where(x => x == 5).Single();
Console.Write(test);

と書いてみたら配列ではなく単一のint型の変数としてアクセスすることができた。

ちゃんと、いろいろと試してみないといけないなぁと思った。

シーケンスの 1 つの特定の要素を返します。

Queryable.Single メソッド (System.Linq)

追記:

コメント欄で教えて貰ったので、そちらを利用した場合のサンプルも作成してみました。

Singleメソッドの中に条件を記述できる。

var test = Enumerable.Range(1,10).Single(x => x == 5);
Console.Write(test);

明らかに、簡潔に記述できて楽ですね。

Whereであることを明示するか、Singleの中に記述するか迷うところではあります。

SignleOrDefaultメソッドを利用する。

シーケンスの 1 つの特定の要素を返します。そのような要素が見つからない場合は既定値を返します。

Queryable.SingleOrDefault メソッド (System.Linq)

var test = Enumerable.Range(1, 10).SingleOrDefault(x => x == 15);
if (test == 0)
{
MessageBox.Show("存在しない。");
}
else
{
MessageBox.Show(test.ToString());
}

こちらは、要素が存在しない時は、要素にあたる型の規定値を返します。

intの場合は0なので、上記のサンプルの場合0だったら要素が存在しなかったことになります。

0も範囲内に含まれているような状況だと判断に困りますが、Null許容型や参照型は規定値がNullなので、利用しやすいかもしれません。

Share