インターフェースのメソッドを呼ぶ構文
最近、他人の日記類をまーったく見てない状態が何ヶ月も続いてたりして、それでもトラックバックもらったときぐらいは見てますよ、っと。
それで、最近 id:NyaRuRu さんからふるーい記事にトラックバックがあったりして、それを思い起こしてて思った IL で表現できるけど C# では構文が用意されていない系のネタなんですが、インターフェスのメソッド(やプロパティ)を参照する構文ってほしくないですかね?
たとえば、仮に演算子 -> で実現されたとして、
interface IFoo { void Add(int value); } class X : IFoo { ... } public void Test(X x) { x->IFoo.Add(1); }
みたいなかんじで、x の実装している Add() を呼び出す構文です。
イメージ的には、
IFoo tmp; (tmp = x).Add(1); …(A)
という感じです。
(x as IFoo).Add(1); …(B)
に近いんですが、これだとコンパイル時エラーにならないのでイメージがすこしずれますね。.NET 2.0 での実装的には、
public static class CallIFoo<T> where T : IFoo { public static void Add(T obj, int value) { obj.Add(value); } } …(C) public void Test(X x) { CallIFoo<X>.Add(x, 1); }
ってかんじで代替できるかな? 逆にこうなってないと困るんですけどね。最初にあったような構文があれば、
interface IBar { int Get(int a); int Get(int a, int b); int Get(int a, int b, int c); } Y : IBar { int IBar.Get(int a) { return this->IBar.Get(a, 1); } int IBar.Get(int a, int b) { return this->IBar.Get(a, 1, 5); } int IBar.Get(int a, int b, int c) { return ...; } }
みたいな明示的実装の呼び出しが簡潔にかけるってものです。
例の (A) や (B) のように、(this as IBar).Get(...) とか常に書けるとは限らなくて、例えば、
public struct IntValue : IFoo, IBar { private int currentValue; public IntValue() { this.currentValue = 0; } void IFoo.Add(int value) { this.currentValue += value; } int IBar.Get(int a) { ... } }
みたいな場合、(A) や (B) のような実装方法をとると、意図しない結果を生んでしまう可能性があるんですね。
(C) の実装なら大丈夫です。この程度なら IBar のタイプは private/protected に用意したメソッドへ全部委譲しちゃっうような形で作りこんじゃったらいいんですが…。