かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

partialクラス

部分型定義(その4)←らへんで話題になってるpartialクラス。
ちょっくら簡単に復習。


とりあえずこんな風に、クラスの定義をばらして書くことが出来るが出来る。

using System;
using System.Collections.Generic;
using System.Text;

namespace PartialSample
{
    /// <summary>
    /// Sampleクラスだ!
    /// </summary>
    partial class Sample
    {
        public void Foo()
        {
            Console.WriteLine("Foo");
        }
    }

    /// <summary>
    /// こっちにもSampleクラスだ!
    /// </summary>
    partial class Sample
    {
        public void Boo()
        {
            Console.WriteLine("Boo");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            // FooもBooもつかえる
            Sample s = new Sample();
            s.Foo();
            s.Boo();
        }
    }

}

これは、基本なので問題なし。
ということで、ちょっと請った事するとぶちあたりそうなこと。

Generic

Genericを使ったクラスだと…

using System;
using System.Collections.Generic;
using System.Text;

namespace PartialSample
{
    /// <summary>
    /// Sampleクラスだ!
    /// </summary>
    partial class Sample<T>
    {
        public void Foo(T t)
        {
            Console.WriteLine(t);
        }
    }

    /// <summary>
    /// こっちにもSampleクラスだ!
    /// </summary>
    partial class Sample<T>
    {
        public void Boo(T u)
        {
            Console.WriteLine(u);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            // FooもBooもつかえる
            Sample<string> s = new Sample<string>();
            s.Foo("a");
            s.Boo("b");
        }
    }

}

こんな具合になる。

これが

partial class Sample<T> ....

partial class Sample<U> .... // 名前違う!?

だとコンパイルエラーになる。
同じ名前で同じ順序でGenericの引数を指定しないといけない。

継承

Genericは同じパラメータを同じようにつけないといけない。
継承は…?

using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;

namespace PartialSample
{
    /// <summary>
    /// こっちはComponent
    /// </summary>
    partial class Sample<T> : Component
    {
        public void Foo(T t)
        {
            Console.WriteLine(t);
        }
    }

    /// <summary>
    /// こっちはIComparable
    /// </summary>
    partial class Sample<T> : IComparable
    {
        public void Boo(T u)
        {
            Console.WriteLine(u);
        }

        #region IComparable メンバ

        public int CompareTo(object obj)
        {
            EventHandlerList l = this.Events; // Componentのメンバにアクセス出来る
            return 0;
        }

        #endregion
    }

    class Program
    {
        static void Main(string[] args)
        {
            // FooもBooもつ変える
            Sample<string> s = new Sample<string>();
            s.Foo("a");
            s.Boo("b");
            s.CompareTo(new Sample<string>()); // Comparableのメンバもちゃんと呼べる
        }
    }

}

かなり柔軟にやってくれる。

下のほうのSampleでComponentの継承を付け足してもOK。
同じならいいんだって。

もちろん同じpartialクラスで違うクラスを継承するように書くとコンパイルエラー。