<?xml version="1.0" encoding="UTF-8" ?> <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C#</title><link>http://blogs.wankuma.com/hirase/category/1700.aspx</link><description>C#</description><managingEditor>T.Hirase</managingEditor><dc:language>ja-JP</dc:language><generator>.Text Version 0.95.2004.102</generator><item><dc:creator>T.Hirase</dc:creator><title>[C/C++/CLI/C#] 二値Enum型を作りたい。 </title><link>http://blogs.wankuma.com/hirase/archive/2009/07/30/179566.aspx</link><pubDate>Thu, 30 Jul 2009 23:39:00 GMT</pubDate><guid>http://blogs.wankuma.com/hirase/archive/2009/07/30/179566.aspx</guid><wfw:comment>http://blogs.wankuma.com/hirase/comments/179566.aspx</wfw:comment><comments>http://blogs.wankuma.com/hirase/archive/2009/07/30/179566.aspx#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://blogs.wankuma.com/hirase/comments/commentRss/179566.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/hirase/services/trackbacks/179566.aspx</trackback:ping><description>&lt;p&gt;うすたー：&lt;a href="http://blogs.wankuma.com/hirase/archive/2009/07/17/177879.aspx"&gt;[C#] Enumを二値扱いたかったりする。&lt;/a&gt;&lt;p&gt;
&lt;p&gt;うすたー：&lt;a href="http://blogs.wankuma.com/rti/archive/2009/07/27/179358.aspx"&gt;Enum で bool 型を使いたい時って？&lt;/a&gt; (R.Tanaka.Ichiro's Blog)&lt;p&gt;
&lt;p&gt;前回の記事があまりにひどいできだったので、やり直します。&lt;/p&gt;
&lt;h3&gt;戻り値はtrue/falseでいいですか？&lt;/h3&gt;
&lt;p&gt;たとえば、データの書き込み関数「&lt;code&gt;TryWritingBytes&lt;/code&gt;」を考えます。バッファリングやハードウェアの都合上、書き込みには失敗する可能性があります。&lt;/p&gt;
&lt;p&gt;以下に、&lt;code&gt;TryWritingBytes&lt;/code&gt;関数の使用例を示します。同関数の実装は省略。&lt;/p&gt;
&lt;pre class="c" xml:space="preserve" name="sourceCode"&gt;extern bool TryWritingBytes(void * data, size_t size);

int main()
{
	// something to do.
	
	if (TryWritingBytes(data, size)) {
		// 成功時の処理
	} else {
		// 失敗時の処理
	}
	
	// something to do.
}
&lt;/pre&gt;
&lt;p&gt;この&lt;code&gt;TryWritingBytes&lt;/code&gt;の戻り値は、書き込み成功時に&lt;code&gt;true&lt;/code&gt;を返す仕様になります。が、こういう「成功=Trueだな」みたいに、経験十分プログラマ的な感覚で決められた関数って、危ういと思います。みんながみんな経験十分プログラマとは限らないからです。&lt;/p&gt;
&lt;h3&gt;成功不成功という値を作るべし。&lt;/h3&gt;
&lt;p&gt;そんなわけで、trueがどっちを表すかなんて、不毛な議論やコメントを書くくらいなら、さっさと別の二値型を作って、読む人も書く人も間違えないようにすべきです。&lt;/p&gt;
&lt;p&gt;そんなこんなで、このコード：&lt;/p&gt;
&lt;pre class="c" xml:space="preserve" name="sourceCode"&gt;enum IsSuccess : bool {
	Success,
	Failed
};

extern IsSuccess TryWritingBytes(void * data, size_t size);

int main()
{
	// something to do.
	
	if (TryWritingBytes(data, size) == Success) {
		// 成功時の処理
	} else {	// Failed
		// 失敗時の処理
	}
	
	// something to do.
}
&lt;/pre&gt;
&lt;p&gt;こんな言語仕様あった方がいいと思いません？&lt;/p&gt;
&lt;h3&gt;補足&lt;/h3&gt;
&lt;p&gt;先の記事で、私、「true/falseを別名で扱いたいだけです」と書いていますが、考え直したところ、全然ダメです。true/falseを別名で扱うこともやはり手段であって、目的ではないですし、仮にできたとしても、所詮別名、成功不成功を表す別名にtrue/falseを代入できてしまいますから。&lt;/p&gt;
&lt;p&gt;なので、やっぱり、二値Enum。&lt;/p&gt;
&lt;p&gt;また先の記事のコメントやトラックバックで、いくつか代替方法をいただきましたが、やはり私を含む経験不足プログラマが見てもわかりやすい方式（二値Enumに限らず）が言語仕様に組み込まれる方が良いと思います。&lt;/p&gt;
&lt;p&gt;ちなみに、別に今回の二値Enumがベストな解だとは思っていません。&lt;/p&gt;
&lt;p&gt;あとあと、最後に。他にも言語仕様に不満ってありません？　っていうか何でテキストエディタなんだよ？　とか。クラスのメソッドを編集するのに、どのファイルを開けばいいかなんて、覚えるのなんて意味ないよ？　とか。もっと自由にやらせろ、的な。&lt;/p&gt;

&lt;h3&gt;追記＠2009-07-30T23:40&lt;/h3&gt;
&lt;p&gt;Success/False以外の例をいくつか。&lt;/p&gt;
&lt;pre class="c" xml:space="preserve" name="sourceCode"&gt;
enum OpenClose : bool { Open, Close };
OpenClose CheckOpenClose();
OpenClose OpenTray();

enum YesNo : bool { Yes, No };
YesNo CheckResponse();
YesNo WaitResponse();

enum GoodBad : bool { Good, Bad };
GoodBad CheckFile(const char * file_name);

enum MaleFemale : bool { Male, Female };
MaleFemale CheckSexuality();
&lt;/pre&gt;
&lt;p&gt;などなど&lt;/p&gt;
&lt;img src ="http://blogs.wankuma.com/hirase/aggbug/179566.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>T.Hirase</dc:creator><title>[C#] Enumを二値扱いたかったりする。</title><link>http://blogs.wankuma.com/hirase/archive/2009/07/17/177879.aspx</link><pubDate>Fri, 17 Jul 2009 11:34:00 GMT</pubDate><guid>http://blogs.wankuma.com/hirase/archive/2009/07/17/177879.aspx</guid><wfw:comment>http://blogs.wankuma.com/hirase/comments/177879.aspx</wfw:comment><comments>http://blogs.wankuma.com/hirase/archive/2009/07/17/177879.aspx#Feedback</comments><slash:comments>1923</slash:comments><wfw:commentRss>http://blogs.wankuma.com/hirase/comments/commentRss/177879.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/hirase/services/trackbacks/177879.aspx</trackback:ping><description>&lt;p&gt;以下、妄想コード。&lt;/p&gt;
&lt;pre class="csharp" xml:space="preserve" name="sourceCode"&gt;enum ProcResult : bool  /* 2値であることを宣言 */
{
    Success,
    Failure,
}

class Program
{
    static void Main(string[] args)
    {
        ProcResult v = ProcResult.Success;
        v = !v; /* 2値なんで、「!」演算したいよぅ。 */

        System.Console.WriteLine(v);
    }
}
&lt;/pre&gt;
&lt;img src ="http://blogs.wankuma.com/hirase/aggbug/177879.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>T.Hirase</dc:creator><title>[C#] char.IsLetter('あ') == True??!</title><link>http://blogs.wankuma.com/hirase/archive/2009/06/18/175768.aspx</link><pubDate>Thu, 18 Jun 2009 00:53:00 GMT</pubDate><guid>http://blogs.wankuma.com/hirase/archive/2009/06/18/175768.aspx</guid><wfw:comment>http://blogs.wankuma.com/hirase/comments/175768.aspx</wfw:comment><comments>http://blogs.wankuma.com/hirase/archive/2009/06/18/175768.aspx#Feedback</comments><slash:comments>12</slash:comments><wfw:commentRss>http://blogs.wankuma.com/hirase/comments/commentRss/175768.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/hirase/services/trackbacks/175768.aspx</trackback:ping><description>&lt;p&gt;MSDN曰く「&lt;a href="http://msdn.microsoft.com/ja-jp/library/system.char.isletter.aspx"&gt;指定した Unicode 文字がアルファベット文字かどうかを示します。&lt;/a&gt;」ですが、表題とおり、「あ」は True となります。&lt;/p&gt;
&lt;p&gt;２００４年に川俣氏が「&lt;a href="http://mag.autumn.org/Content.modf?id=20040505145723"&gt;「あ」がアルファベット扱い?　.NET FrameworkのChar.IsDigitとChar.IsLetterの正しい挙動&lt;/a&gt;」で指摘されていますが、未だに直っていないようです。&lt;/p&gt;
&lt;p&gt;メソッド名通りの正しい動作だとは思いますが、残念なことにドキュメントが間違っています。というかアメリカ人は「Letter=Alphabet」だったのでしょうね。実装を確かめずにドキュメントを書くと、こうなるようです。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/hirase/aggbug/175768.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>T.Hirase</dc:creator><title>[C#] Visual Studio アドインで新規ウィンドウを作成する。</title><link>http://blogs.wankuma.com/hirase/archive/2009/05/08/172559.aspx</link><pubDate>Fri, 08 May 2009 02:23:00 GMT</pubDate><guid>http://blogs.wankuma.com/hirase/archive/2009/05/08/172559.aspx</guid><wfw:comment>http://blogs.wankuma.com/hirase/comments/172559.aspx</wfw:comment><comments>http://blogs.wankuma.com/hirase/archive/2009/05/08/172559.aspx#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://blogs.wankuma.com/hirase/comments/commentRss/172559.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/hirase/services/trackbacks/172559.aspx</trackback:ping><description>&lt;p&gt;参考：&lt;a href="http://msdn.microsoft.com/ja-jp/library/envdte80.windows2.createtoolwindow2.aspx"&gt;Windows2.CreateToolWindow2 メソッド &lt;/a&gt; (MSDN)&lt;/p&gt;
&lt;p&gt;メモでございます。&lt;/p&gt;
&lt;pre class="csharp" xml:space="preserve" name="sourceCode"&gt;public void Exec(string commandName, vsCommandExecOption executeOption, ref object varIn, ref object varOut, ref bool handled)
{
    handled = false;
    if (executeOption == vsCommandExecOption.vsCommandExecOptionDoDefault)
    {
        if (commandName == "Sample.Connect.SampleWindow")
        {
            Windows2 windows = this._addInInstance.DTE.Windows as Windows2;
            if (windows == null)
                return;

            Assembly thisAssembly = Assembly.GetAssembly(this.GetType());
            object controlObject = null;
            Window window;
            window = windows.CreateToolWindow2(this._addInInstance, thisAssembly.Location, "Sample.MyUserControl", "Sample Window", "{374A85F2-DA7E-4ab0-8E0F-998E2FED0F55}", ref controlObject);
            if (window != null)
            {
                window.Visible = true;
            }
            handled = true;
            return;
        }
    }
}
&lt;/pre&gt;
&lt;p&gt;あらかじめ、UserControl を継承した Sample.MyUserControl クラスを作っておく必要があります。&lt;/p&gt;
&lt;p&gt;このコードは、Visual Studio 2008 で生成したコードを元に追加したものです。&lt;/p&gt;
&lt;p&gt;以上&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/hirase/aggbug/172559.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>T.Hirase</dc:creator><title>[C#] 複素数型を作る。</title><link>http://blogs.wankuma.com/hirase/archive/2009/02/05/167505.aspx</link><pubDate>Thu, 05 Feb 2009 10:37:00 GMT</pubDate><guid>http://blogs.wankuma.com/hirase/archive/2009/02/05/167505.aspx</guid><wfw:comment>http://blogs.wankuma.com/hirase/comments/167505.aspx</wfw:comment><comments>http://blogs.wankuma.com/hirase/archive/2009/02/05/167505.aspx#Feedback</comments><slash:comments>1859</slash:comments><wfw:commentRss>http://blogs.wankuma.com/hirase/comments/commentRss/167505.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/hirase/services/trackbacks/167505.aspx</trackback:ping><description>&lt;p&gt;元ネタ：&lt;a href="http://blogs.wankuma.com/izmktr/archive/2009/02/05/167489.aspx"&gt;[C#]コンプレックスと戦う&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;C# ジェネリクスの制限に打ち勝つ&lt;/h4&gt;
&lt;p&gt;型制約として値型を用いることができない、operator+-*/ をGetMethod()できない、そんな C# ジェネリックでも、複素数型を定義してみました。&lt;/p&gt;
&lt;pre class="csharp" xml:space="preserve" name="sourceCode"&gt;namespace Sample
{
    using System;
    using System.ComponentModel;

    struct Complex&amp;lt;TValue&amp;gt;
    {
        public TValue Real { get; set; }
        public TValue Imaginary { get; set; }

        public static Complex&amp;lt;TValue&amp;gt; operator +(Complex&amp;lt;TValue&amp;gt; lft, Complex&amp;lt;TValue&amp;gt; rgt)
        {
            return new Complex&amp;lt;TValue&amp;gt;() { Real = Adder(lft.Real, rgt.Real), Imaginary = Adder(lft.Imaginary, rgt.Imaginary) };
        }

        public static Complex&amp;lt;TValue&amp;gt; operator -(Complex&amp;lt;TValue&amp;gt; lft, Complex&amp;lt;TValue&amp;gt; rgt)
        {
            return new Complex&amp;lt;TValue&amp;gt;() { Real = Subtractor(lft.Real, rgt.Real), Imaginary = Subtractor(lft.Imaginary, rgt.Imaginary) };
        }

        public static Complex&amp;lt;TValue&amp;gt; operator *(Complex&amp;lt;TValue&amp;gt; lft, Complex&amp;lt;TValue&amp;gt; rgt)
        {
            return new Complex&amp;lt;TValue&amp;gt;() { Real = Multiplier(lft.Real, rgt.Real), Imaginary = Multiplier(lft.Imaginary, rgt.Imaginary) };
        }

        public static Complex&amp;lt;TValue&amp;gt; operator /(Complex&amp;lt;TValue&amp;gt; lft, Complex&amp;lt;TValue&amp;gt; rgt)
        {
            return new Complex&amp;lt;TValue&amp;gt;() { Real = Divider(lft.Real, rgt.Real), Imaginary = Divider(lft.Imaginary, rgt.Imaginary) };
        }

        static Complex()
        {
            var tvalue_type = typeof(TValue);
            if (tvalue_type == typeof(sbyte))
            {
                Complex&amp;lt;sbyte&amp;gt;.Adder = (x, y) =&amp;gt; (sbyte)(x + y);
                Complex&amp;lt;sbyte&amp;gt;.Subtractor = (x, y) =&amp;gt; (sbyte)(x - y);
                Complex&amp;lt;sbyte&amp;gt;.Multiplier = (x, y) =&amp;gt; (sbyte)(x * y);
                Complex&amp;lt;sbyte&amp;gt;.Divider = (x, y) =&amp;gt; (sbyte)(x / y);
            }
            else if (tvalue_type == typeof(byte))
            {
                Complex&amp;lt;byte&amp;gt;.Adder = (x, y) =&amp;gt; (byte)(x + y);
                Complex&amp;lt;byte&amp;gt;.Subtractor = (x, y) =&amp;gt; (byte)(x - y);
                Complex&amp;lt;byte&amp;gt;.Multiplier = (x, y) =&amp;gt; (byte)(x * y);
                Complex&amp;lt;byte&amp;gt;.Divider = (x, y) =&amp;gt; (byte)(x / y);
            }
            else if (tvalue_type == typeof(short))
            {
                Complex&amp;lt;short&amp;gt;.Adder = (x, y) =&amp;gt; (short)(x + y);
                Complex&amp;lt;short&amp;gt;.Subtractor = (x, y) =&amp;gt; (short)(x - y);
                Complex&amp;lt;short&amp;gt;.Multiplier = (x, y) =&amp;gt; (short)(x * y);
                Complex&amp;lt;short&amp;gt;.Divider = (x, y) =&amp;gt; (short)(x / y);
            }
            else if (tvalue_type == typeof(ushort))
            {
                Complex&amp;lt;ushort&amp;gt;.Adder = (x, y) =&amp;gt; (ushort)(x + y);
                Complex&amp;lt;ushort&amp;gt;.Subtractor = (x, y) =&amp;gt; (ushort)(x - y);
                Complex&amp;lt;ushort&amp;gt;.Multiplier = (x, y) =&amp;gt; (ushort)(x * y);
                Complex&amp;lt;ushort&amp;gt;.Divider = (x, y) =&amp;gt; (ushort)(x / y);
            }
            else if (tvalue_type == typeof(int))
            {
                Complex&amp;lt;int&amp;gt;.Adder = (x, y) =&amp;gt; (int)(x + y);
                Complex&amp;lt;int&amp;gt;.Subtractor = (x, y) =&amp;gt; (int)(x - y);
                Complex&amp;lt;int&amp;gt;.Multiplier = (x, y) =&amp;gt; (int)(x * y);
                Complex&amp;lt;int&amp;gt;.Divider = (x, y) =&amp;gt; (int)(x / y);
            }
            else if (tvalue_type == typeof(uint))
            {
                Complex&amp;lt;uint&amp;gt;.Adder = (x, y) =&amp;gt; (uint)(x + y);
                Complex&amp;lt;uint&amp;gt;.Subtractor = (x, y) =&amp;gt; (uint)(x - y);
                Complex&amp;lt;uint&amp;gt;.Multiplier = (x, y) =&amp;gt; (uint)(x * y);
                Complex&amp;lt;uint&amp;gt;.Divider = (x, y) =&amp;gt; (uint)(x / y);
            }
            else if (tvalue_type == typeof(long))
            {
                Complex&amp;lt;long&amp;gt;.Adder = (x, y) =&amp;gt; (long)(x + y);
                Complex&amp;lt;long&amp;gt;.Subtractor = (x, y) =&amp;gt; (long)(x - y);
                Complex&amp;lt;long&amp;gt;.Multiplier = (x, y) =&amp;gt; (long)(x * y);
                Complex&amp;lt;long&amp;gt;.Divider = (x, y) =&amp;gt; (long)(x / y);
            }
            else if (tvalue_type == typeof(ulong))
            {
                Complex&amp;lt;ulong&amp;gt;.Adder = (x, y) =&amp;gt; (ulong)(x + y);
                Complex&amp;lt;ulong&amp;gt;.Subtractor = (x, y) =&amp;gt; (ulong)(x - y);
                Complex&amp;lt;ulong&amp;gt;.Multiplier = (x, y) =&amp;gt; (ulong)(x * y);
                Complex&amp;lt;ulong&amp;gt;.Divider = (x, y) =&amp;gt; (ulong)(x / y);
            }
            else if (tvalue_type == typeof(float))
            {
                Complex&amp;lt;float&amp;gt;.Adder = (x, y) =&amp;gt; (float)(x + y);
                Complex&amp;lt;float&amp;gt;.Subtractor = (x, y) =&amp;gt; (float)(x - y);
                Complex&amp;lt;float&amp;gt;.Multiplier = (x, y) =&amp;gt; (float)(x * y);
                Complex&amp;lt;float&amp;gt;.Divider = (x, y) =&amp;gt; (float)(x / y);
            }
            else if (tvalue_type == typeof(double))
            {
                Complex&amp;lt;double&amp;gt;.Adder = (x, y) =&amp;gt; (double)(x + y);
                Complex&amp;lt;double&amp;gt;.Subtractor = (x, y) =&amp;gt; (double)(x - y);
                Complex&amp;lt;double&amp;gt;.Multiplier = (x, y) =&amp;gt; (double)(x * y);
                Complex&amp;lt;double&amp;gt;.Divider = (x, y) =&amp;gt; (double)(x / y);
            }
            else if (tvalue_type == typeof(decimal))
            {
                Complex&amp;lt;decimal&amp;gt;.Adder = (x, y) =&amp;gt; (decimal)(x + y);
                Complex&amp;lt;decimal&amp;gt;.Subtractor = (x, y) =&amp;gt; (decimal)(x - y);
                Complex&amp;lt;decimal&amp;gt;.Multiplier = (x, y) =&amp;gt; (decimal)(x * y);
                Complex&amp;lt;decimal&amp;gt;.Divider = (x, y) =&amp;gt; (decimal)(x / y);
            }
            else
            {
                throw new NotSupportedException();
            }
        }

        private static Func&amp;lt;TValue, TValue, TValue&amp;gt; Adder { get; set; }
        private static Func&amp;lt;TValue, TValue, TValue&amp;gt; Subtractor { get; set; }
        private static Func&amp;lt;TValue, TValue, TValue&amp;gt; Multiplier { get; set; }
        private static Func&amp;lt;TValue, TValue, TValue&amp;gt; Divider { get; set; }

        public override string ToString()
        {
            return String.Format("({0}) + ({1})i", Real.ToString(), Imaginary.ToString());
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            #region +
            Console.WriteLine((new Complex&amp;lt;sbyte&amp;gt; { Real = 1, Imaginary = 1 } + new Complex&amp;lt;sbyte&amp;gt; { Real = 1, Imaginary = 2 }).ToString());
            Console.WriteLine((new Complex&amp;lt;byte&amp;gt; { Real = 1, Imaginary = 1 } + new Complex&amp;lt;byte&amp;gt; { Real = 1, Imaginary = 2 }).ToString());
            Console.WriteLine((new Complex&amp;lt;short&amp;gt; { Real = 1, Imaginary = 1 } + new Complex&amp;lt;short&amp;gt; { Real = 1, Imaginary = 2 }).ToString());
            Console.WriteLine((new Complex&amp;lt;ushort&amp;gt; { Real = 1, Imaginary = 1 } + new Complex&amp;lt;ushort&amp;gt; { Real = 1, Imaginary = 2 }).ToString());
            Console.WriteLine((new Complex&amp;lt;int&amp;gt; { Real = 1, Imaginary = 1 } + new Complex&amp;lt;int&amp;gt; { Real = 1, Imaginary = 2 }).ToString());
            Console.WriteLine((new Complex&amp;lt;uint&amp;gt; { Real = 1, Imaginary = 1 } + new Complex&amp;lt;uint&amp;gt; { Real = 1, Imaginary = 2 }).ToString());
            Console.WriteLine((new Complex&amp;lt;long&amp;gt; { Real = 1, Imaginary = 1 } + new Complex&amp;lt;long&amp;gt; { Real = 1, Imaginary = 2 }).ToString());
            Console.WriteLine((new Complex&amp;lt;ulong&amp;gt; { Real = 1, Imaginary = 1 } + new Complex&amp;lt;ulong&amp;gt; { Real = 1, Imaginary = 2 }).ToString());
            Console.WriteLine((new Complex&amp;lt;float&amp;gt; { Real = 1, Imaginary = 1 } + new Complex&amp;lt;float&amp;gt; { Real = 1, Imaginary = 2 }).ToString());
            Console.WriteLine((new Complex&amp;lt;double&amp;gt; { Real = 1, Imaginary = 1 } + new Complex&amp;lt;double&amp;gt; { Real = 1, Imaginary = 2 }).ToString());
            Console.WriteLine((new Complex&amp;lt;decimal&amp;gt; { Real = 1, Imaginary = 1 } + new Complex&amp;lt;decimal&amp;gt; { Real = 1, Imaginary = 2 }).ToString());
            #endregion
            #region -
            Console.WriteLine((new Complex&amp;lt;sbyte&amp;gt; { Real = 1, Imaginary = 1 } - new Complex&amp;lt;sbyte&amp;gt; { Real = 1, Imaginary = 2 }).ToString());
            Console.WriteLine((new Complex&amp;lt;byte&amp;gt; { Real = 1, Imaginary = 1 } - new Complex&amp;lt;byte&amp;gt; { Real = 1, Imaginary = 2 }).ToString());
            Console.WriteLine((new Complex&amp;lt;short&amp;gt; { Real = 1, Imaginary = 1 } - new Complex&amp;lt;short&amp;gt; { Real = 1, Imaginary = 2 }).ToString());
            Console.WriteLine((new Complex&amp;lt;ushort&amp;gt; { Real = 1, Imaginary = 1 } - new Complex&amp;lt;ushort&amp;gt; { Real = 1, Imaginary = 2 }).ToString());
            Console.WriteLine((new Complex&amp;lt;int&amp;gt; { Real = 1, Imaginary = 1 } - new Complex&amp;lt;int&amp;gt; { Real = 1, Imaginary = 2 }).ToString());
            Console.WriteLine((new Complex&amp;lt;uint&amp;gt; { Real = 1, Imaginary = 1 } - new Complex&amp;lt;uint&amp;gt; { Real = 1, Imaginary = 2 }).ToString());
            Console.WriteLine((new Complex&amp;lt;long&amp;gt; { Real = 1, Imaginary = 1 } - new Complex&amp;lt;long&amp;gt; { Real = 1, Imaginary = 2 }).ToString());
            Console.WriteLine((new Complex&amp;lt;ulong&amp;gt; { Real = 1, Imaginary = 1 } - new Complex&amp;lt;ulong&amp;gt; { Real = 1, Imaginary = 2 }).ToString());
            Console.WriteLine((new Complex&amp;lt;float&amp;gt; { Real = 1, Imaginary = 1 } - new Complex&amp;lt;float&amp;gt; { Real = 1, Imaginary = 2 }).ToString());
            Console.WriteLine((new Complex&amp;lt;double&amp;gt; { Real = 1, Imaginary = 1 } - new Complex&amp;lt;double&amp;gt; { Real = 1, Imaginary = 2 }).ToString());
            Console.WriteLine((new Complex&amp;lt;decimal&amp;gt; { Real = 1, Imaginary = 1 } - new Complex&amp;lt;decimal&amp;gt; { Real = 1, Imaginary = 2 }).ToString());
            #endregion
            #region *
            Console.WriteLine((new Complex&amp;lt;sbyte&amp;gt; { Real = 1, Imaginary = 1 } * new Complex&amp;lt;sbyte&amp;gt; { Real = 1, Imaginary = 2 }).ToString());
            Console.WriteLine((new Complex&amp;lt;byte&amp;gt; { Real = 1, Imaginary = 1 } * new Complex&amp;lt;byte&amp;gt; { Real = 1, Imaginary = 2 }).ToString());
            Console.WriteLine((new Complex&amp;lt;short&amp;gt; { Real = 1, Imaginary = 1 } * new Complex&amp;lt;short&amp;gt; { Real = 1, Imaginary = 2 }).ToString());
            Console.WriteLine((new Complex&amp;lt;ushort&amp;gt; { Real = 1, Imaginary = 1 } * new Complex&amp;lt;ushort&amp;gt; { Real = 1, Imaginary = 2 }).ToString());
            Console.WriteLine((new Complex&amp;lt;int&amp;gt; { Real = 1, Imaginary = 1 } * new Complex&amp;lt;int&amp;gt; { Real = 1, Imaginary = 2 }).ToString());
            Console.WriteLine((new Complex&amp;lt;uint&amp;gt; { Real = 1, Imaginary = 1 } * new Complex&amp;lt;uint&amp;gt; { Real = 1, Imaginary = 2 }).ToString());
            Console.WriteLine((new Complex&amp;lt;long&amp;gt; { Real = 1, Imaginary = 1 } * new Complex&amp;lt;long&amp;gt; { Real = 1, Imaginary = 2 }).ToString());
            Console.WriteLine((new Complex&amp;lt;ulong&amp;gt; { Real = 1, Imaginary = 1 } * new Complex&amp;lt;ulong&amp;gt; { Real = 1, Imaginary = 2 }).ToString());
            Console.WriteLine((new Complex&amp;lt;float&amp;gt; { Real = 1, Imaginary = 1 } * new Complex&amp;lt;float&amp;gt; { Real = 1, Imaginary = 2 }).ToString());
            Console.WriteLine((new Complex&amp;lt;double&amp;gt; { Real = 1, Imaginary = 1 } * new Complex&amp;lt;double&amp;gt; { Real = 1, Imaginary = 2 }).ToString());
            Console.WriteLine((new Complex&amp;lt;decimal&amp;gt; { Real = 1, Imaginary = 1 } * new Complex&amp;lt;decimal&amp;gt; { Real = 1, Imaginary = 2 }).ToString());
            #endregion
            #region /
            Console.WriteLine((new Complex&amp;lt;sbyte&amp;gt; { Real = 1, Imaginary = 1 } / new Complex&amp;lt;sbyte&amp;gt; { Real = 1, Imaginary = 2 }).ToString());
            Console.WriteLine((new Complex&amp;lt;byte&amp;gt; { Real = 1, Imaginary = 1 } / new Complex&amp;lt;byte&amp;gt; { Real = 1, Imaginary = 2 }).ToString());
            Console.WriteLine((new Complex&amp;lt;short&amp;gt; { Real = 1, Imaginary = 1 } / new Complex&amp;lt;short&amp;gt; { Real = 1, Imaginary = 2 }).ToString());
            Console.WriteLine((new Complex&amp;lt;ushort&amp;gt; { Real = 1, Imaginary = 1 } / new Complex&amp;lt;ushort&amp;gt; { Real = 1, Imaginary = 2 }).ToString());
            Console.WriteLine((new Complex&amp;lt;int&amp;gt; { Real = 1, Imaginary = 1 } / new Complex&amp;lt;int&amp;gt; { Real = 1, Imaginary = 2 }).ToString());
            Console.WriteLine((new Complex&amp;lt;uint&amp;gt; { Real = 1, Imaginary = 1 } / new Complex&amp;lt;uint&amp;gt; { Real = 1, Imaginary = 2 }).ToString());
            Console.WriteLine((new Complex&amp;lt;long&amp;gt; { Real = 1, Imaginary = 1 } / new Complex&amp;lt;long&amp;gt; { Real = 1, Imaginary = 2 }).ToString());
            Console.WriteLine((new Complex&amp;lt;ulong&amp;gt; { Real = 1, Imaginary = 1 } / new Complex&amp;lt;ulong&amp;gt; { Real = 1, Imaginary = 2 }).ToString());
            Console.WriteLine((new Complex&amp;lt;float&amp;gt; { Real = 1, Imaginary = 1 } / new Complex&amp;lt;float&amp;gt; { Real = 1, Imaginary = 2 }).ToString());
            Console.WriteLine((new Complex&amp;lt;double&amp;gt; { Real = 1, Imaginary = 1 } / new Complex&amp;lt;double&amp;gt; { Real = 1, Imaginary = 2 }).ToString());
            Console.WriteLine((new Complex&amp;lt;decimal&amp;gt; { Real = 1, Imaginary = 1 } / new Complex&amp;lt;decimal&amp;gt; { Real = 1, Imaginary = 2 }).ToString());
            #endregion
        }
    }
}
&lt;/pre&gt;

&lt;p&gt;ちなみに、string でも Adder だけは定義可能なので、επιστημη氏の「&lt;a href="http://blogs.wankuma.com/episteme/archive/2009/02/04/167390.aspx"&gt;あらあらあら&lt;/a&gt;」も C# で可能。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/hirase/aggbug/167505.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>T.Hirase</dc:creator><title>[C#] ジェネリック＋型情報で頑張る「文字列→値」変換</title><link>http://blogs.wankuma.com/hirase/archive/2009/01/23/166655.aspx</link><pubDate>Fri, 23 Jan 2009 10:20:00 GMT</pubDate><guid>http://blogs.wankuma.com/hirase/archive/2009/01/23/166655.aspx</guid><wfw:comment>http://blogs.wankuma.com/hirase/comments/166655.aspx</wfw:comment><comments>http://blogs.wankuma.com/hirase/archive/2009/01/23/166655.aspx#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://blogs.wankuma.com/hirase/comments/commentRss/166655.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/hirase/services/trackbacks/166655.aspx</trackback:ping><description>&lt;p&gt;Ｒ・田中一郎さんの「&lt;a href="http://blogs.wankuma.com/rti/archive/2009/01/22/166614.aspx"&gt;またジェネリックで挫折&lt;/a&gt;」しないように、ジェネリック＋型情報で頑張る日記。&lt;/p&gt;
&lt;pre class="csharp" xml:space="preserve" name="sourceCode"&gt;namespace Sample
{
    using System;
    using System.ComponentModel;
    using System.Diagnostics;

    static class Program
    {
        static void Main(string[] args)
        {
            var value = ToNumeric&amp;lt;Decimal&amp;gt;("10.2");
            Console.WriteLine(value);
        }

        static public T ToNumeric&amp;lt;T&amp;gt;(string value)
        {
            if (value == null) return default(T);

            if (String.IsNullOrEmpty(value)) return default(T);

            try
            {
                var converter = GetNumericConverter&amp;lt;T&amp;gt;();
                if (converter != null &amp;&amp; converter.CanConvertFrom(typeof(String)))
                {
                    return (T)converter.ConvertFromString(value);
                }
            }
            catch (Exception e)  // Exception を捕りたくないんだけど、他に方法がない。
            {
                Debug.WriteLine(e.Message);
            }
            return default(T);
        }

        static BaseNumberConverter GetNumericConverter&amp;lt;T&amp;gt;()
        {
            Type typeInfo = typeof(T);

            if (typeInfo == typeof(Byte)) return new ByteConverter();
            if (typeInfo == typeof(Decimal)) return new DecimalConverter();
            if (typeInfo == typeof(Double)) return new DoubleConverter();
            if (typeInfo == typeof(Int16)) return new Int16Converter();
            if (typeInfo == typeof(Int32)) return new Int32Converter();
            if (typeInfo == typeof(Int64)) return new Int64Converter();
            if (typeInfo == typeof(SByte)) return new SByteConverter();
            if (typeInfo == typeof(Single)) return new SingleConverter();
            if (typeInfo == typeof(UInt16)) return new UInt32Converter();
            if (typeInfo == typeof(UInt32)) return new UInt32Converter();
            if (typeInfo == typeof(UInt64)) return new UInt32Converter();

            return null;
        }
    }
}&lt;/pre&gt;

&lt;img src ="http://blogs.wankuma.com/hirase/aggbug/166655.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>T.Hirase</dc:creator><title>仕事のブログ更新</title><link>http://blogs.wankuma.com/hirase/archive/2008/12/09/163034.aspx</link><pubDate>Tue, 09 Dec 2008 09:35:00 GMT</pubDate><guid>http://blogs.wankuma.com/hirase/archive/2008/12/09/163034.aspx</guid><wfw:comment>http://blogs.wankuma.com/hirase/comments/163034.aspx</wfw:comment><comments>http://blogs.wankuma.com/hirase/archive/2008/12/09/163034.aspx#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://blogs.wankuma.com/hirase/comments/commentRss/163034.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/hirase/services/trackbacks/163034.aspx</trackback:ping><description>&lt;p&gt;こんなの書きました↓&lt;/p&gt;
&lt;p&gt;CRIチャンネル「&lt;a href="http://ch.cri-mw.co.jp/hirase/52620.html"&gt;ミドルウェアにしてミドルウェアにあらず。&lt;/a&gt;」。&lt;/p&gt;
&lt;p&gt;よろしくどうぞ。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/hirase/aggbug/163034.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>T.Hirase</dc:creator><title>[C#] カスタム コントロールをローカライズできないのは何故？</title><link>http://blogs.wankuma.com/hirase/archive/2008/11/23/161968.aspx</link><pubDate>Sun, 23 Nov 2008 14:43:00 GMT</pubDate><guid>http://blogs.wankuma.com/hirase/archive/2008/11/23/161968.aspx</guid><wfw:comment>http://blogs.wankuma.com/hirase/comments/161968.aspx</wfw:comment><comments>http://blogs.wankuma.com/hirase/archive/2008/11/23/161968.aspx#Feedback</comments><slash:comments>177</slash:comments><wfw:commentRss>http://blogs.wankuma.com/hirase/comments/commentRss/161968.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/hirase/services/trackbacks/161968.aspx</trackback:ping><description>&lt;p&gt;最近作ったとあるカスタム コントロールを Windows Form に貼ったときに、なぜか Windows Form の Localizable プロパティを操作できなくなっていました。現象は以下の通り。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Localizable プロパティを操作したときに「プロパティの値が無効です」ダイアログが出る。&lt;/li&gt;
&lt;li&gt;そのダイアログの詳細には「オブジェクト参照がオブジェクト インスタンスに設定されていません。」と出る。&lt;/li&gt;
&lt;li&gt;Localizable プロパティの値が True から False に変わる場合でも、False から True に変わる場合でも現象は同じ。&lt;/li&gt;
&lt;li&gt;件のカスタムコントロールを外せば、Localizable プロパティを操作できる。&lt;/li&gt;
&lt;li&gt;この現象が起きているとき、ビルドした際にはローカライズ済みリソースが出力されない。（もちろん Localizable プロパティが True になっている。）&lt;/li&gt;
&lt;li&gt;カスタムコントロール内には null ポインタを逆参照しているようなプロパティもない。（そんなのあったら、Localizable 云々の前に発見できるはず。）&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;ところで。&lt;/p&gt;
&lt;h4&gt;Localizable プロパティはどこにある？&lt;/h4&gt;
&lt;p&gt;このデバッグしているときに、今更気付いたのですが、System.Windows.Forms.Form.Localizable なんてプロパティは存在しません。デバッグのためにコード上で Localizable プロパティを操作しようと思ったのですが、そんなものありませんでした。Localizable プロパティと Language プロパティは、は、System.ComponentModel.Design.Serialization.CodeDomLocalizationProvider 拡張プロバイダによって提供されるプロパティでありました。&lt;/p&gt;
&lt;p&gt;（拡張プロバイダによって追加されるプロパティで有名なのは、ToolTip のプロパティかな。）&lt;/p&gt;
&lt;p&gt;さてさて。&lt;/p&gt;
&lt;h4&gt;何が悪さをしていたのか？&lt;/h4&gt;
&lt;p&gt;答えは、カスタム コントロールに設定していた、カスタムのデザイナ内のとあるイベントハンドラ。&lt;/p&gt;
&lt;p&gt;いうか、これ→&lt;a href="http://msdn.microsoft.com/ja-jp/library/ms171820.aspx"&gt;「方法 : デザイン モードでコントロールの外観と動作を拡張する」&lt;/a&gt;のサンプルソース内の「changeService_ComponentChanged()」メソッド（ページ内検索してくださいね）。&lt;/p&gt;
&lt;pre class="csharp" xml:space="preserve" name="sourceCode"&gt;void changeService_ComponentChanged(object sender, ComponentChangedEventArgs e)
{
    if (object.ReferenceEquals(
        e.Component, 
        this.relatedControl))
    {
        if (e.Member.Name == "Margin" ||
            e.Member.Name == "Padding" )
        {
            this.marginAndPaddingAdorner.Invalidate();
        }
    }
}&lt;/pre&gt;
&lt;p&gt;ここの、イベントソース ComponentChangedEventArgs のプロパティ Member が null でした。&lt;/p&gt;
&lt;p&gt;えぇ・・。所詮はサンプルソースということなのですね。&lt;/p&gt;

&lt;img src ="http://blogs.wankuma.com/hirase/aggbug/161968.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>T.Hirase</dc:creator><title>[C#] スタティックなメンバは、そのクラスが始めて使われるときに初期化されるという誤解でハマった８月のある日</title><link>http://blogs.wankuma.com/hirase/archive/2008/10/02/158019.aspx</link><pubDate>Thu, 02 Oct 2008 22:28:00 GMT</pubDate><guid>http://blogs.wankuma.com/hirase/archive/2008/10/02/158019.aspx</guid><wfw:comment>http://blogs.wankuma.com/hirase/comments/158019.aspx</wfw:comment><comments>http://blogs.wankuma.com/hirase/archive/2008/10/02/158019.aspx#Feedback</comments><slash:comments>599</slash:comments><wfw:commentRss>http://blogs.wankuma.com/hirase/comments/commentRss/158019.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/hirase/services/trackbacks/158019.aspx</trackback:ping><description>&lt;p&gt;C# にて、「スタティックなメンバは、そのクラスが始めて使われるときに初期化されるという誤解」をしていたという、ある自分のある８月の話。&lt;/p&gt;
&lt;p&gt;次のようなコードで、不思議なことが起こります。&lt;/p&gt;
&lt;pre class="csharp" xml:space="preserve" name="sourceCode"&gt;
using System;
using System.Windows.Forms;

public class MyForm : Form
{
    private MyForm()
    {
        MessageBox.Show("Called \"MyForm.MyForm()\"");
    }

    static MyForm defaultForm = new MyForm();
    public static MyForm Default
    {
        get { return defaultForm; }
    }
}

static class Program
{
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        MessageBox.Show("Do \"Application.Run(MyForm.Default);\"");
        Application.Run(MyForm.Default);
    }
}
&lt;/pre&gt;
&lt;h4&gt;スタティックなメンバの初期化タイミングに関する罠&lt;/h4&gt;
&lt;p&gt;上記のコードで、Program.Main() 中の Application.SetCompatibleTextRenderingDefault(false); ですが、このメソッドは、Form の初期化前に呼ぶ必要があります。Form を初期化してから呼び出すと、以下のような例外が起こります。&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;System.InvalidOperationException はハンドルされませんでした。
  Message="最初の IWin32Window オブジェクトがアプリケーションで作成される前に、SetCompatibleTextRenderingDefault が呼び出されなければなりません。"
  Source="System.Windows.Forms"
  StackTrace:
       場所 System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(Boolean defaultValue)
       場所 Program.Main() 場所 D:\CodeGagdet\TestStaticClass\TestStaticClass\Program.cs:行 25
       場所 System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
       場所 System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       場所 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       場所 System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       場所 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       場所 System.Threading.ThreadHelper.ThreadStart()
  InnerException: 
&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;上記のコードでも、きちんとこの順番を守って呼び出している「つもり」です。&lt;/p&gt;
&lt;p&gt;しかし、よく見ると、MyForm は自身のインスタンスをスタティックメンバー defaultForm として持っています。&lt;/p&gt;
&lt;p&gt;この defaultForm の初期化は、「MyForm が初めて使用される Application.Run() 時に行われる」ものだと思っていたら痛い目にあいました。。&lt;/p&gt;
&lt;h4&gt;実行条件によって変わるスタティックメンバーの初期化タイミング&lt;/h4&gt;
&lt;p&gt;実は、スタティックなメンバーの初期化タイミングは、実行条件によって変わっていました。&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;Debugビルド + デバッグあり実行&lt;/dt&gt;&lt;dd&gt;初めて MyForm が使用される MyForm.Defaul プロパティの呼び出し直前。&lt;/dd&gt;
&lt;dt&gt;Debugビルド + デバッグなし実行&lt;/dt&gt;&lt;dd&gt;同上&lt;/dd&gt;
&lt;dt&gt;Releaseビルド + デバッグあり実行&lt;/dt&gt;&lt;dd&gt;同上&lt;/dd&gt;
&lt;dt&gt;Releaseビルド + デバッグなし実行&lt;/dt&gt;&lt;dd&gt;Program.Main関数に入ったとき。あるいは、その直前。&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;４つ目のケース「Releaseビルド + デバッグなし実行」では、defaultForm が Application.SetCompatibleTextRenderingDefault() より手前で初期化されます。&lt;/p&gt;
&lt;p&gt;これでは、先に挙げた例外 InvalidOperationException が発生します。&lt;/p&gt;
&lt;p&gt;もちろん、上手くいく系もあるでしょうし、逆に Debug モードでだって上手くいかない系もあるかと思います。&lt;/p&gt;
&lt;h4&gt;解決方法（追記＠2008-10-03）&lt;/h4&gt;
&lt;pre class="csharp:firstline[11]" xml:space="preserve" name="sourceCode"&gt;    static MyForm defaultForm;
    public static MyForm Default
    {
        get
        {
            if (defaultForm == null)
                defaultForm = new MyForm();
            return defaultForm;
        }
    }
&lt;/pre&gt;
&lt;p&gt;スタティックなメンバーのインスタンス生成を自分が意図したタイミングまで引き伸ばしますことで解決しました。&lt;/p&gt;
&lt;p&gt;コメント欄にもあるように、スタティックなコンストラクタを用意することでも解決するようですが、これもタイミングが本当に一定なのかがわからないという意味で、やめた方が良いでしょう。&lt;/p&gt;
&lt;h4&gt;まとめ&lt;/h4&gt;
&lt;p&gt;スタティックなメンバーの初期化は、いつ行われるかわかりません。&lt;/p&gt;
&lt;p&gt;少なくとも初めてそのクラスが使われるまでには初期化されますが、今回のようなケースだとだいぶ痛い目に合います。&lt;/p&gt;
&lt;p&gt;そんなこんなで、気をつけましょうね、という日記でした。&lt;/p&gt;

&lt;img src ="http://blogs.wankuma.com/hirase/aggbug/158019.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>T.Hirase</dc:creator><title>[C++/C#] インタフェースっていったい・・・？</title><link>http://blogs.wankuma.com/hirase/archive/2008/07/14/148849.aspx</link><pubDate>Mon, 14 Jul 2008 22:00:00 GMT</pubDate><guid>http://blogs.wankuma.com/hirase/archive/2008/07/14/148849.aspx</guid><wfw:comment>http://blogs.wankuma.com/hirase/comments/148849.aspx</wfw:comment><comments>http://blogs.wankuma.com/hirase/archive/2008/07/14/148849.aspx#Feedback</comments><slash:comments>9</slash:comments><wfw:commentRss>http://blogs.wankuma.com/hirase/comments/commentRss/148849.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/hirase/services/trackbacks/148849.aspx</trackback:ping><description>&lt;h4&gt;C++0xのコンセプトの話&lt;/h4&gt;
&lt;p&gt;&lt;a href="http://d.hatena.ne.jp/faith_and_brave/"&gt;アキラさん&lt;/a&gt;のC++0xの資料を拝見して、コンセプトって、なんでインタフェースっていう名前にならなかったのか疑問に思ったのは自分だけ？&lt;/p&gt;
&lt;p&gt;だって、インタフェースと機能は同じで、しばりが少ないってだけな印象なのに。。同じダックタイピングなのに。&lt;/p&gt;
&lt;p&gt;いうなれば、コンセプトがインタフェースらしく振舞うのであれば、それは最早インタフェースだと思う。&lt;/p&gt;
&lt;h4&gt;C#のインタフェースの話&lt;/h4&gt;
&lt;p&gt;なんで継承/実装していないとキャストできないのか不思議。明示的に継承していない場合でも、関係なしにダウンキャストできていいと思うのですが。。&lt;/p&gt;
&lt;p&gt;こんな感じ↓&lt;/p&gt;
&lt;pre class="csharp" xml:space="preserve" name="sourceCode"&gt;
using System;
interface IMyMeMine
{
    void Hello();
}

class SayHello
{
    public void Hello() { Console.WriteLine("Hello"); }
}

class Program
{
    static void Main(String[] args)
    {
        Hello(new SayHello());
    }

    static void Hello&amp;lt;T&amp;gt;(T t) where T:IMyMeMine
    {
        t.Hello();
    }
}
&lt;/pre&gt;
&lt;p&gt;たとえばシステムのクラスをジェネリックに扱いたい場合に、ときどきやりたい。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/hirase/aggbug/148849.aspx" width = "1" height = "1" /&gt;</description></item></channel></rss>