C#で継承元を指定したジェネリッククラスを作成したいです。


System.Windows.FormsのPanelとLabelを継承したカスタムコントロール(PanelEx、LabelEx)を作成していますが、それぞれに共通した処理があるため、切り出して別クラス(classLib)に実装したいと考えています。

この共通した処理の中にはPanelとLabelの継承元であるControlのprotectedメソッドを呼び出す処理もあるためclassLibの継承元を指定して宣言したいのです。

つまり以下のようなことがしたいです。
class classLib<T> : T
class PanelEx : classLib<Panel>
class LabelEx : classLib<Label>

しかし、ジェネリックの型パラメータは派生させることができず困っています。
こういうことはそもそもできないのでしょうか?それとも別の方法で実現できる手段が提供されているのでしょうか?

回答の条件
  • 1人5回まで
  • 登録:
  • 終了:2011/09/21 09:58:29
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

回答1件)

id:heke2mee No.1

回答回数162ベストアンサー獲得回数43

ポイント200pt

これでどうでしょうか

型パラメータの制約が必要ならば追加してください

    public class TestGen<T> : Control
    {
        public void TestControl()
        {
            base.CreateHandle();
        }
    }

    public class PanelEx : TestGen<Panel>
    {        
    }

    public class LabelEx : TestGen<Label>
    {
    }
id:mstkwb

回答有難う御座います。

提示いただいたコードの場合、Tに与えたPanelやLabelの機能はどうなりますか?

両方共Controlの派生クラスになってしまうのではないでしょうか?

2011/09/18 17:59:00
  • id:heke2mee
    遅くなって申し訳ありません。

    ご指摘の通りControlの継承になっているので
    LabelやPanel固有のメソッド等は使用できません。

    もしTの継承ができたとしても、TはPanelやLableに変化するので
    ジェネリッククラスのなかでT.XXXという方法でPanelやLableの固有のメソッドを
    呼び出すことはできません




    Protectedのメソッドを公開することは余りいい方法だと思いませんが
    このようにすると、たぶんご希望のことができると思います。
    (internalにすると少しはまし)

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Windows.Forms;
    using System.Drawing;

    namespace TestControl
    {
    public interface IControlEx
    {
    /// <summary>
    /// Protectedへのアクセス
    /// </summary>
    void ProtectedMethodAccess();
    }


    public class LabelEx : Label, IControlEx
    {
    public void ProtectedMethodAccess()
    {
    // プロテクトなメソッド
    base.CreateHandle();
    }
    }

    public class PanelEx : Panel, IControlEx
    {
    public void ProtectedMethodAccess()
    {
    // プロテクトなメソッド
    base.CreateHandle();
    }
    }


    public static class Util
    {
    /// <summary>
    /// パネル固有の処理
    /// </summary>
    public static void Method(PanelEx pnl)
    {
    Util.ControlExMethod<PanelEx>(pnl);
    }

    /// <summary>
    /// ラベル固有の処理
    /// </summary>
    public static void Method(LabelEx lbl)
    {
    Util.ControlExMethod<LabelEx>(lbl);
    }

    /// <summary>
    /// コントロールEx共通の処理
    ///
    /// ControlやIControlExを継承したクラスへの処理を記述
    /// </summary>
    public static void ControlExMethod<T>(T ctlEx)
    where T : Control, IControlEx
    {
    ctlEx.ProtectedMethodAccess();
    }
    }
    }
  • id:mstkwb
    ありがとうございます。
    やはりこの様な形になりますよね... コード例までご提示頂きありがとうございました。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません