interface in C#

C# の interface は Java の interface と同じようなもんらしいんだがそもそも Java をまともに書いたことがないのにその理解はどうなんだ。まぁ C++ の純粋仮想 class みたいなもんだという理解でいいか的な。

で、 C# の場合 interface のみで class library を作ることができる、ということに気づいて驚いた。いやまぁそもそも C# って #include がないから interface をどうにか外から参照できる方法がないとダメっていう制限からきてるというのはなんとなく想像つくんだけど。

それいったら #include がなくて project 間の参照ですべて解決してしまうというのはうーんわかりやすいがわかりにくい。 header や source を最終的に preprocessor が file ていう翻訳単位に落とすんだ !! という世界で今までやってきたのでそれより上の layer でやるんですうちは !! と言われてはぁまぁそうですかみたいな感覚。

というかこれ Visual Studio みたいな IDE 使わないと楽にはならなかったりするんじゃなかろうか ? source level で参照解決しないので手打ちで build する場合 compiler か linker の option につらつら何かがつきそうな予感。 source にそこらへん指定する方法あるのかもだけどうーん、 IDE への囲い込みのようにも思える ( 穿ち過ぎ ) 。

そしてなんで .Net Framework にはあんなに dll が多いのかちょっとわかった気がする。 interface のみ dll とその version 違いとか interface の実装が数種類あってさらにそいつらの version 違いとか考えるとそりゃ dll 多くなるよ。

まぁ慣れ、なのかなぁ。 project 作成と build 用に IDE は立ち上げるけど source の編集は vim でみたいな運用 ? Intellisense が便利なのはいいんだけど環境のいじり方含めてその他がアレすぎて Visual Studio とか使いたくないんだよかんべんしてくれよ。

あー何を言ってるかというと以下のような source を持つ、たとえば "ITest" という class library project があったとして、

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

namespace Test
{
    public interface IPerson
    {
        string Name { get; set; }
        DateTime BirthDay { get; set; }
        int Age();
    }
}

以下のような console application project を "ITest" を使って実装しようとすると "ITest" への参照を以下の project に追加してやらないといけない。 Visual Studio だと project 名の context menu から「参照の追加」して「プロジェクト」 tab の "ITest" を選んで「 OK 」を押す、という step が必要になる。

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

namespace ConsoleApplication
{
    class Person : Test.IPerson
    {
        string _name;
        DateTime _birthDay;

        public Person(string name, DateTime birthDay)
        {
            this._name = name;
            this._birthDay = birthDay;
        }

        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }

        public DateTime BirthDay
        {
            get { return _birthDay; }
            set { _birthDay = value; }
        }

        public int Age()
        {
            TimeSpan delta = DateTime.Now - BirthDay;
            return delta.Days / 365;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Person yuta = new Person("Yuta", new DateTime(2008,3,1));
            Console.WriteLine(yuta.Name + "\n");
            Console.WriteLine(yuta.BirthDay + "\n");
            Console.WriteLine(yuta.Age() + " years old\n");
        }
    }
}

はっ、優太さん Person じゃなかった !!