9
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

特定のクラスを継承していて、かつ特定のインターフェースを実装している型を受け付けるメソッドの作り方

Last updated at Posted at 2013-09-17

型Aを継承していて、かつインターフェースIBを実装しているような型だけを引数に受け付けたい。

以下、型A=System.Web.UI.Page、インターフェースB=IHogePage とする。

方法1.cs
// Page または IHogePage を引数にして中で型チェック。不正なら例外を投げる。
public void Hoge(Page page)
{
    var hoge = page as IHogePage;
    if (hoge == null) throw new ArgumentException();
    page.Controls.Add(new TextBox { ID = hoge.HogeMember });
}

public interface IHogePage
{
    string HogeMember { get; }
}
  • メリット
    • .NET的に素直?
  • デメリット
    • IHogePage を実装していなければいけないことがシグネチャから伝わらない
    • IHogePage を実装していない型のインスタンスを渡してしまっても実行時までエラーにならない
方法2.cs
// Page を継承していて IHogePage を実装する抽象クラスを作る
public void Hoge(HogePage page)
{
    page.Controls.Add(new TextBox { ID = page.HogeMember });
}

public interface IHogePage
{
    string HogeMember { get; }
}
public abstract class HogePage : Page, IHogePage
{
    public abstract string HogeMember { get; }
}
  • メリット
    • 型安全になる
  • デメリット
    • HogePage 以外を継承したいクラスに対応できない
方法3.cs
// ジェネリックメソッドにして型制約で 2 つの型を強制させる
public void Hoge<T>(T t)
    where T : Page, IHogePage
{
    t.Controls.Add(new TextBox { ID = t.HogeMember });
}

public interface IHogePage
{
    string HogeMember { get; }
}
  • メリット
    • 型安全かつ好きなクラスを継承してもらえる
  • デメリット
    • ジェネリック本来の使い方と違う気が

方法3がベストな気がしていますが、本来ジェネリックである必要はないので気持ち悪さが残るところ。

9
11
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?