< October 2008 | November 2008 | December 2008 >

November 21, 2008

静的な定数

インスタンス数を制限するクラスを定義する必要がよくある。実装方法のひとつに、コンストラクタを隠蔽して、静的メソッド内でインスタンス数チェックを行いインスタンスを返させる手法が考えられる。というわけで、こんな風に書いたとする。

class Kanjo
{
    // インスタンス数
    private static int instansNum = 0;

    // 三人官女は 3 人まで
    private static const int maxInstansNum = 3;

    // 静的なメソッドよりインスタンスを作成する
    public static Kanjo CreateInstance ()
    {
        // インスタンス数チェック
        if (instansNum < maxInstansNum)
        {
            instansNum++;           // インスタンス数を加算
            return new Kanjo ();    // 官女を作成して返す
        }
        // 例外の種類は適当
        throw new OverflowException ();
    }

    private Kanjo ()
    {
        // 官女の初期化を行う
    }
}

上記のコードはコンパイルできない。「定数 'Kanjo.maxInstansNum' を static に指定することはできません。」というエラーになってしまう。static const なんて C++ だと普通のコードなので少々悩んだ。C# の場合は const をつけた時点で静的メンバになるので、static をつけることが出来ない。const をつけると static がなくとも静的なメソッドからアクセス可能になる。

// static がつかなくても、静的なメソッドからアクセスが可能
const int maxInstansNum = 3;

なんか気持ちわるー。

ちなみに、C# には readonly というキーワードもあるが、こちらはインスタンスが作られるので、下記の記述が可能。

// readonly の場合は static をつけないと静的なメンバにならない
static readonly int maxInstansNum = 3;

メモ: Wireshark のフィルタの書き方忘れちゃったよ!

すっかり忘れちゃったよ ! 勉強勉強 !!

フィルタ作成方法[Etherealを使おう]

キャプチャフィルタは tcpdump のを指定。
Manpage of TCPDUMP

November 17, 2008

メモ: Custom Sort for DataBound WPF ListView

    CodeProject: Custom Sort for DataBound WPF ListView. Free source code and programming help

    メモ: ソート可能な ListView

    A Sortable GridView (I mean ListView) Control in WPF

    A Sortable GridView (I mean ListView) Control in WPF(翻訳中)

    A Sortable GridView (I mean ListView) Control in WPF

    続きを読む...

    November 14, 2008

    C# には friend キーワードがない

    いまさら気づきましたが…。C++ から来た人間としてはかなり不便に感じます。別案を考えなきゃな。

    参考になるかもなぎろん。
    フレンドクラスに対する代替案 - C#、VB.NET、ASP.NET、C /CLI、Java

    November 13, 2008

    Binding の StringFormat プロパティが反映されない

    .NET Frameworks 3.5 SP1 より、BindingBase に StringFormat プロパティが追加されて、話題になりました。が、こんなの書いてみてもちっともフォーマットされず、悩みました。

    <Window x:Class="StringFormatTest.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:System="clr-namespace:System;assembly=mscorlib"
        Title="Window1">
        <Window.Resources>
            <ObjectDataProvider x:Key="DayOfWeek" MethodName="GetValues" ObjectType="{x:Type System:Enum}">
                <ObjectDataProvider.MethodParameters>
                    <x:Type TypeName="System:DayOfWeek"/>
                </ObjectDataProvider.MethodParameters>
            </ObjectDataProvider>
        </Window.Resources>
    
        <ListBox ItemsSource="{Binding Source={StaticResource DayOfWeek}, StringFormat={}{0}!}"/>
    </Window>
    

    これは、ItemsControl クラスの ItemStringFormat プロパティの値のほうが優先されるためです。こちらは、意図したとおりに「!」が追加されて表示されます。

    <ListBox ItemsSource="{Binding Source={StaticResource DayOfWeek}}" ItemStringFormat="{}{0}!"/>
    

    その他、ContentControl を継承するコントロールの場合 ContentStringFormat プロパティが、HeaderedContentControl や HeaderedItemsControl の場合、HeaderStringFormat プロパティが存在して、Binding に設定した StringFormat より優先されるようです。

    November 7, 2008

    メモ: コマンド

    WPFの「コマンド」 - .NET Claimwork 3.0

    コマンドの使い方がさっくりかかれててわかりやすいです。

    November 6, 2008

    拡張メソッドを使用して、DateTime 型で年齢計算を利用できるようにする

    XmlSerializer を使う (シリアル化編) で Person クラスの年齢の計算がてきとうだったので、この辺を参考にして拡張メソッドを作ってみました。

    namespace DateTimeExtensions
    {
        public static class GetAgeExtension
        {
            public static int GetAge (this DateTime birthDay, DateTime today)
            {
                DateTime tempDate = new DateTime (birthDay.Year, 1, 1);
                tempDate = tempDate.AddDays (today.DayOfYear - 1);
                return today.Year - birthDay.Year + (birthDay <= tempDate ? 0 : -1);
            }
        }
    }
    

    これでこんな風に書けますね。

    // ソースの先頭に以下を追加
    // using DateTimeExtensions;
    
    // Person の配列を作る
    var people = Enumerable.Range (0, 5)
        .Select (index => new { index = index, day = new DateTime (1975 + index, index + 1, index + 1) })
        .Select (param => new Person ()
        {
            Name = string.Format ("{0:ddd}", param.day) + suffix [param.index % 2],
            Gender = (GenderEnum) (param.index % 2),
            Birthday = param.day,
            Age = param.day.GetAge (DateTime.Now)   // こんな感じで!
        }).ToArray ();
    

    メモ: スレッド処理

    スレッド処理 (C# プログラミング ガイド)

    XmlSerializer を使う (シリアル化編)

    System.Xml.Serialization 名前空間に XmlSerializer というクラスがある。その名のとおり、データを XML 形式でシリアル化してくれるというもの。

    シリアル化するクラスは public でないといけないらしい。クラスメンバについても public なプロパティや変数が対象になる。メソッドは対象とならない。また、get/set の両方が可能である必要がある。

    また、デフォルトコンストラクタのないクラスは扱えない。メンバにも含めることが出来ない。

    // 性別
    public enum GenderEnum : int { Male, Female, }
    
    // ありがちなクラス
    public class Person
    {
        public string Name { get; set; }
        public GenderEnum Gender { get; set; }
        public DateTime Birthday { get; set; }
        public int Age { get; set; }
    }
    

    上記 Person クラスのシリアライズはこんな感じ。

    using System;
    using System.Linq;
    
    class XmlSerializeSample
    {
        static void Main ()
        {
            // 名前生成用w
            var suffix = new string [] { "郎", "子" };
    
            // Person の配列を作る
            var people = Enumerable.Range (0, 5)
                .Select (index => new { index = index, day = new DateTime (1975 + index, index + 1, index + 1) })
                .Select (param => new Person ()
                {
                    Name = string.Format ("{0:ddd}", param.day) + suffix [param.index % 2],
                    Gender = (GenderEnum) (param.index % 2),
                    Birthday = param.day,
                    Age = DateTime.Now.Year - param.day.Year    // 年齢が適当ですね…
                }).ToArray ();
    
            // XmlSerializer を使用したシリアライズ
            var serializer = new System.Xml.Serialization.XmlSerializer (typeof (Person []));
            var stream = new System.IO.StreamWriter("C:\\people.xml", false);
            serializer.Serialize(stream, people);
            stream.Close();
        }
    }
    
    続きを読む...

    November 5, 2008

    メモ: WPF アプリケーションのローカライズ方法

    川西 裕幸のブログ : LocBAML

    LocBAML を使用してローカライズする方法が説明されています。ただし、UICulture の記述を .csproj ファイルに追加する際は、閉じタグ部分に気をつける必要があります。

    <UICulture>ja-JP</UICulture>

    November 4, 2008

    メモ: XML シリアル化を制御する属性

    XML シリアル化を制御する属性

    メモ:カスタム DateTime 書式指定文字列

    カスタム DateTime 書式指定文字列