none
列挙体の拡張(継承)のようなことを実現したい RRS feed

  • 質問

  • 列挙体の拡張(継承)のようなことを実現したいと考えております。

    ただ、列挙体自体が継承を許可していないため、実現できず 実現方法を模索しております。

    どなたかアドバイスをいただけませんでしょうか。

    もしくは、そもそもこういった考え方自体がおかしのでしょうか。

    [やりたいこと]

    1.開発者が複数おり、ID類は一塊にして、汎用部分、特化部分をわけ

     汎用部分をこちらでつくり、それを継承した特化部分をほかのメンバーに触らせるようにしたい

    2. 実装のことを考え、任意関数呼び出し時の引数指定時には候補一覧がでるようにしたい

     (関数呼び出し時、引数がenumだった場合その値しか出ないかとおもいます。)

    [例]

    自分が作り提供する基底enum

    enum ID{

      NAME

    , ADDRESS

    }

    ユーザーが使う場合

    enum ID2 : ID{

    NEW_FIELD1

    }

    この場合、関数の引数等でこの値のくくりを使用する場合、候補値として

    NAME, ADDRESS, NEW_FIELDがでるようにしたい。

    2012年12月18日 14:01

回答

  • 複数開発者がいるプロジェクトということで、お手軽な方法で回避するなら、構造体にしてしまってもいいんじゃないですか?

    下記のような感じなら、Method1(ID. とすれば補完候補に NAME, ADDRESS, NEW_FIELD1がでますし、複数の開発者で名前がかぶっていればコンパイルエラーにもなります。enum のような自動付番が必要ならコンストラクタや初期化用のメソッドなんかで都合のよいように好きに作り込めます。(開発者毎やカテゴリ毎に付番ルールをつけるなど)

    まあ、あまりよい方法とはいえませんが、目的によっては妥協できる範囲かな?と。

    // 開発者A (ID.cs)
    public partial struct ID
    {
        public static readonly ID NAME;
        public static readonly ID ADDRESS;
       // 基本的な実装...コンストラクタとかを書いておく
    }
    // 開発者B (ID_b.cs)
    public partial struct ID
    {
        public static readonly ID NEW_FIELD1
    }
    // 使う場所
    public void Method1(ID id) { ... }

    • 回答としてマーク dgi dgi dgi 2012年12月20日 14:21
    2012年12月19日 13:06

すべての返信

  • ご期待に添えるかどうか。「enum 継承」で検索してみた。

    http://bbs.wankuma.com/index.cgi?mode=al2&namber=9118&KLOG=21

    http://npnl.hatenablog.jp/entry/2012/05/03/103145 (すべて表示されるのに少々時間がかかりました)


    Jitta@わんくま同盟

    2012年12月18日 14:31
  • 「できない」ので違うことを考えるべきでしょうね。
    Jitta さんのリンクされているスレッドにあるような、クラスで列挙値もどきを作るのが候補かなと思います。

    // 多くの型に共通の enum のような存在があると、メンテナンスが大変な気もしなくもないです。
    // 共通部分が増えたときの作業量が大変そうな気もしますが、その辺は大丈夫な考え方なんだろうか。

    2012年12月18日 14:52
    モデレータ
  • 実現できません。

    例えばですが、.NET Frameworkでは、色を表すColor構造体があります。青と黄色とかを表すためにstaticメンバーとして定義されています。更に追加部分としてSystemColorsクラスで定義されているものもあります。enumでなく構造体であれば、このような定義の仕方もできます。

    どうしてもenumでという場合は、T4テキストテンプレートでenumの定義を動的に生成するとか。ただし既定enumが別アセンブリですとどうしようもないです。

    2012年12月18日 15:07
  • 複数開発者がいるプロジェクトということで、お手軽な方法で回避するなら、構造体にしてしまってもいいんじゃないですか?

    下記のような感じなら、Method1(ID. とすれば補完候補に NAME, ADDRESS, NEW_FIELD1がでますし、複数の開発者で名前がかぶっていればコンパイルエラーにもなります。enum のような自動付番が必要ならコンストラクタや初期化用のメソッドなんかで都合のよいように好きに作り込めます。(開発者毎やカテゴリ毎に付番ルールをつけるなど)

    まあ、あまりよい方法とはいえませんが、目的によっては妥協できる範囲かな?と。

    // 開発者A (ID.cs)
    public partial struct ID
    {
        public static readonly ID NAME;
        public static readonly ID ADDRESS;
       // 基本的な実装...コンストラクタとかを書いておく
    }
    // 開発者B (ID_b.cs)
    public partial struct ID
    {
        public static readonly ID NEW_FIELD1
    }
    // 使う場所
    public void Method1(ID id) { ... }

    • 回答としてマーク dgi dgi dgi 2012年12月20日 14:21
    2012年12月19日 13:06
  • みなさんが書かれているようにenumの継承はできませんから、何らかの代替手段を取るしかありません。その一つとして、動的にenumを作成するという方法が取れるかもしれません。

    (参考)

    列挙型を動的に作成
    http://social.msdn.microsoft.com/Forums/ja/csharpgeneralja/thread/db50fabb-836e-4737-a650-368a8b760746


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/

    2012年12月20日 1:33
    モデレータ
  •  深く考えず、「どこかでそんな質問見たな-」と思って検索をかけましたが・・・ところで、enum って、いつ使いたいでしょう?どちらかというと、実行時というより、コードを書いているときに何らかの値を明示的に示すために使いたいのではないでしょうか。
    また、どのように使うために求めているのかにもよるのかもしれませんが、チーム開発であれば、互いに同じ値を同じ値として使わなければ意味がないと思います。同じ値を別の意味で用いていれば、メンテナンスする時に困ります。

     そういうことを考えると、メンバーがそれぞれ別個に追加できるというのは、どうなんでしょう?

     あるいは、C で言うところの #define を意図されているのかもしれませんが、それであれば、佐佑理さんやK.Takaokaさんの構造体案の方が良いと思います。ただ、本当に1つの構造体(列挙でも)にまとめる必然性があるのか、もう一度設計を見直してみる方が良いのではないでしょうか。


    Jitta@わんくま同盟

    2012年12月20日 13:43