Quantcast
Channel: C#タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9509

C#に於いてinterfaceがinterfaceを継承した場合について私が知っている二、三の事柄

$
0
0
interface が interface を継承するって? 正直言って、これは行儀の良い作法ではない。アンチパターン一歩手前である。しかし、C#の文法的に許されていることだし、利点も十分あるので議論の価値はあるだろう。 即ち、以下の様なコードである。 public interface IFoo { int DoSomething(); } public interface IBar : IFoo { double DoOtherThing(); } public class SomeClass : IBar { /// <summary> /// IFooのメソッド実装。IBarには書かれていないが、継承しているため実装が必要。 /// </summary> public int DoSomething() { return 530000; } /// <summary> /// IBarのメソッド実装。 /// </summary> public double DoOtherThing() { return 5.55; } } 長所 IFooが必要となるメソッドにIBarのインスタンスを入れることができる。 SomeClassにはIFooを明示的に実装しなくてもIFooに変換可能。 interfaceからinterfaceを派生させたいということは割とある(例えばモジュールのinterfaceを結合したinterfaceを作るなど)ので、それなりに需要はあると思う。 短所 IFooを見るだけではIFooがどのメソッドを要求しているかが分からない。 SomeClassがIFooインターフェイスを実装していることがコードだけでは分からない。 一応、どのメソッドを実装すべきかはVisual StudioなどのIDEが教えてくれるだろうが、分かりづらいことは確かである。 interfaceでメンバが被った場合 当然ながらinterfaceは多重継承できる。その場合に発生するのがメンバ被りだ。例えば次の場合を考える。 public interface IHoge { int Something { get; set; } // その他メンバ省略 } public interface IPiyo { int Something { get; set; } // その他メンバ省略 } public interface IFuga : IHoge, IPiyo { // その他メンバ省略 } public class Fuga : IFuga { public int Something { get; set; } // その他実装は省略 } public void main() { IFuga fuga = new Fuga(); fuga.Something; // ここで警告が出る! } IFugaはコードのどこかでIHoge、IPiyoとして使われることを期待している。 しかし、IFuga経由で両方で定義されているメンバを読み出すと、警告が走る。この場合は型が同じなので警告に留まるが、型が違えばそれぞれを明示的に実装しなければならないし、fuga.Somethingという書き方はできない。 この場合の解法:new宣言の使用 ここでfuga.Somethingとしたいのであれば、IFugaを以下のコードを追加すれば良い。 public interface IFuga : IHoge, IPiyo { // ... new int Something { get; set; } } newと銘打ったことでIFuga.Somethingは上位クラスとのつながりが切れた。しかし、今回の場合は型が同じため、IHoge、IPiyoいずれからでもSomethingを読み出すことができる。

Viewing all articles
Browse latest Browse all 9509

Trending Articles