読者です 読者をやめる 読者になる 読者になる

No more Death March

あるSEのチラシの裏 C# WPF

C# 拡張メソッドについてメモ

C#

拡張メソッド (C# プログラミング ガイド)

拡張メソッドは別クラスで宣言した静的なメソッドをインスタンスメソッドのように記述出来るもの。

まずは拡張メソッドでメソッドで追加するクラス

namespace Nmdm
{
    public sealed class Hoge
    {
    }
}

そして拡張メソッド

namespace Nmdm
{
    public static class HogeExtension
    {
        public static void ExtensionMethod(this Hoge obj)
        {
        }
    }
}

このように静的なメソッドの第一引数にthisという記述をすると、第一引数の型に対する拡張メソッドの宣言となる。

使う場合は以下のようにする。

namespace Nmdm
{
    public sealed class HogeClient
    {
        public void DoSomething()
        {
            var hoge = new Hoge();
            hoge.ExtensionMethod();
        }
    }
}

あくまでインスタンスメソッドのように見せかけて記述出来るだけであって、
実態はstaticメソッドです。

そのため、以下のように記述することも出来ます。

namespace Nmdm
{
    public sealed class HogeClient
    {
        public void DoSomething()
        {
            var hoge = new Hoge();
            // hoge.ExtensionMethod();
            HogeExtension.ExtensionMethod(hoge);
        }
    }
}

インスタンスメソッドに同じスコープ、同じシグネチャのメソッドがある場合、インスタンスメソッドが優先される。

このように拡張メソッドを宣言して。

namespace Nmdm
{
    public static class HogeExtension
    {
        public static void SameMethod(this Hoge obj)
        {
        }
    }
}

同じシグネチャインスタンスメソッドがある場合

namespace Nmdm
{
    public sealed class Hoge
    {
        public void SameMethod()
        {
        }
    }
}

以下の記述で実際に動くのはインスタンスメソッドの方

namespace Nmdm
{
    public sealed class HogeClient
    {
        public void DoSomething()
        {
            var hoge = new Hoge();
            hoge.SameMethod();
        }
    }
}

このような事情から基本ライブラリのクラスに対して拡張メソッドを実装するとバージョン変更により意図しない動作をしてしまう可能性がある。
もし拡張メソッドを使うのであれば完全自作クラスないしは自作インターフェースのみを対象にした方が良さそうですね。


拡張メソッド自体はインスタンスの状態を持つことは出来ないけど、
少し工夫すればC#でもミックスイン(のような)実装が出来そう。



…ていうのをWPFの添付プロパティやビヘイビアを勉強していて思いました。