Hatena::ブログ(Diary)

hiziriexの日記 RSSフィード

2009年09月12日 [メモ][C#]コンストラクタの話2

コンストラクタの疑問

| 17:14

コンストラクタの呼び出し - hiziriexの日記の続きになります。

元々あのクラス定義は、

  1. デフォルトコンストラクタが呼ばれた場合には一定の要素数(例えば3)を指定して初期化
  2. 要素数を指定してコンストラクタを呼び出した場合には{"hoge1", "hoge2", "hoge3"}のようなstring配列で初期化
  3. string配列を指定して呼び出した場合にはそのstring配列をメンバ変数に代入

といった処理のテストのために作ったものなんだ。

だけど、3を指定とか、式だけで処理できる内容なら特に問題ないのだが、文を書かなければならない処理が書けない。

不可能じゃないけど、そのためには別にメソッド定義してそれを呼び出さなければならない。

しかもコンストラクタ内での呼び出しなのでstaticメソッドである必要まである。

public class Hoge
{
    private string[] items;
    public Hoge()
        : this(3)
    {
        Console.WriteLine("Hoge() called");
    }
    public Hoge(int n)
        : this(hoge(n))
    {
        Console.WriteLine("Hoge(" + n + ") called");
    }
    private static string[] hoge(int n)
    {
        string[] items = new string[n];
        for (int i = 0; i < n; i++)
        {
            items[i] = "hoge" + (i + 1);
        }
        return items;
    }
    public Hoge(string[] items)
    {
        this.items = items;
        Console.WriteLine("Hoge(string[] items) called");
    }
}

現状こんなこんな感じになるんだけどいい解決策はないだろうか?

ごちゃごちゃしてまとまらないからこのまま公開します。

2009年09月11日 [メモ][C#]コンストラクタの話

コンストラクタの呼び出し

| 16:52

Hogeクラスのコンストラクタを定義する。

クラス内で定義された他のコンストラクタを呼ぶにはthisを利用する。

この場合、thisで呼び出したコンストラクタがどのタイミングで呼び出されるか調べた。

public class Hoge
{
    public Hoge()
        : this(3)
    {
        Console.WriteLine("Hoge() called");
    }
    public Hoge(int n)
        : this(new string[]{"hoge"})
    {
        Console.WriteLine("Hoge(int n) called");
    }
    public Hoge(string[] items)
    {
        Console.WriteLine("Hoge(string[] items) called");
    }
}

以下は呼び出し元のコード

new Hoge();
new Hoge(3);
new Hoge(new string[] { "hoge", "auau" });

出力は以下のようになった。

Hoge(string[] items) called
Hoge(int x) called
Hoge() called
Hoge(string[] items) called
Hoge(int x) called
Hoge(string[] items) called

以上より、thisで呼び出されるコンストラクタの後に通常の処理が実行されていることがわかる。

2009年09月03日 [メモ][C#][Visual Studio]デザイナの話

Textプロパティのデザイナを複数行に変更

| 00:44

Labelコントロールの様に、プロパティエディタで値を変更するときに複数行エディタがポップアップするように、変更したい。

class HogeControl : System.Windows.Forms.Control
{
    [System.ComponentModel.Editor(
        typeof(System.ComponentModel.Design.MultilineStringEditor),
        typeof(System.Drawing.Design.UITypeEditor))]
    public override string Text { get; set; }
}

とすれば、今のところ正常に動いている。

親クラスのプロパティでないならoverrideはいらない。

2009年08月13日 [メモ][C#]Win32API

C#からWin32APIを呼び出してみた

| 20:41

ほぼ見よう見真似でやってみた。

using System;
using System.Drawing;
using System.Runtime.InteropServices;//DllImportに必要
public class WinApi
{
        //よくわからないけどたぶんメモリ上に連続してデータ並べるってこと
        [StructLayout(LayoutKind.Sequential)]
        //Win32APIで使うデータって.netでは一切定義されてないから定義しないとダメ
        public struct RECT
        {
            public Int32 left, top, right, bottom;
            //コンストラクタ?構造体なんであまり関係ないような気もする。
            //Setterみたいなもんです。たぶん。
            public RECT(Rectangle rect)
            {
                left = rect.Left;
                top = rect.Top;
                right = rect.Right;
                bottom = rect.Bottom;
            }
        }
        //ExtTextOutWはgdi32.dllにあるんですね。知らんけどね。
        //文字コードをUnicodeに指定ってのは、なんとなくわかった。
        [DllImport("gdi32.dll", CharSet = CharSet.Unicode)]
        private static unsafe extern bool ExtTextOutW(IntPtr hdc, Int32 X,
                Int32 Y, UInt32 fuOptions, RECT* lprc, string lpString,
                UInt32 cbCount, IntPtr lpDx);
        public static bool ExtTextOut(IntPtr hdc, Int32 X, Int32 Y,
                UInt32 fuOptions, RECT* lprc, string lpString,
                UInt32 cbCount, IntPtr lpDx)
        {
                unsafe
                {
                        ExtTextOutW(hdc, X, Y, fuOptions, lprc, lpString, cbCount, lpDx);
                }
        }
}

みたいな風に定義しといて、呼び出すときは、また今度にしよう。

これでフォームに文字列を描画できるようになりました。

.netの標準機能でもできるけどね。