C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

ログ内検索
  • キーワードを複数指定する場合は 半角スペース で区切ってください。
  • 検索条件は、(AND)=[A かつ B] (OR)=[A または B] となっています。
  • [返信]をクリックすると返信ページへ移動します。
キーワード/ 検索条件 /
検索範囲/ 強調表示/ ON (自動リンクOFF)
結果表示件数/ 記事No検索/ ON
大文字と小文字を区別する

No.9118 の関連記事表示

<< 0 >>
■9118  enumの継承?
□投稿者/ ぼのぼの -(2007/10/19(Fri) 12:46:40)

    分類:[C#] 

    こんにちは。例えば以下のようなenumがあったとします。

    public enum MusicFormat { WAV, MP3 }
    public enum MusicFormatApple { WAV, MP3, AAC }
    public enum MusicFormatSony { WAV, MP3, ATRAC }
    public enum MusicFormatMS { WAV, MP3, WMA }

    これらが、下記のような関係にあった場合、

    MusicFormat


    ┌───────┼────────┐
    MusicFormatApple MusicFormatSony MusicFormatMS

    クラスだったら
    public class MusicFormatApple : MusicFormat
    のように書きますが、enumの場合似たような記述方法はあるのでしょうか?
    それとも、enumでの継承的な概念は何らかの理由でサポートされていない?
    一応Googleなどで検索してみたのですが、
    キーワードが悪かったのか有用な情報は見つけられませんでした。
親記事 /過去ログ21より / 関連記事表示
削除チェック/

■9125  Re[1]: enumの継承?
□投稿者/ 魔界の仮面弁士 -(2007/10/19(Fri) 13:37:56)
    No9118 (ぼのぼの さん) に返信
    > enumの場合似たような記述方法はあるのでしょうか?
    無いと思いますが、それができないと困るような状況に陥っているのでしょうか?

    > それとも、enumでの継承的な概念は何らかの理由でサポートされていない?
    enum に限らず、値型(ValueType)はすべて継承できないと思います。少なくとも C# の世界では。
    struct AAA にしても、enum BBB にしても、自動的にシールされますし。

    # SDK で、コンパイラ エラー CS0509 について調べると、C# においては
    # 「既定では、構造体はシールされています。」という表現が見つかります。

    > public class MusicFormatApple : MusicFormat
    低レベル言語でも良いのなら、MSIL を使って
     .class public auto ansi sealed MusicFormatApple extends MusicFormat {
    のように書く事は可能ですが、C# の場合、無理にそのような方を定義しても、
    コンパイラ エラー CS0648 『'型名' はこの言語によってサポートされていない型です。』となります。
記事No.9118 のレス /過去ログ21より / 関連記事表示
削除チェック/

■9121  Re[1]: enumの継承?
□投稿者/ 未記入 -(2007/10/19(Fri) 13:03:49)
    enumはSystem.Enumからの派生クラスであり、System.EnumはSystem.ValueTypeからの派生クラスです。
    System.ValueTypeからの派生クラスは値型のクラス(構造体)なので.NETの多くからは継承できないはずです。
    どうしても継承したい場合は普通のクラスに定数フィールドを並べて継承するしかなさそうですね。
記事No.9118 のレス /過去ログ21より / 関連記事表示
削除チェック/

■9124  Re[2]: enumの継承?
□投稿者/ Hongliang -(2007/10/19(Fri) 13:19:04)
>
    例がどうにも。
    [Flags] enum MusicFormats { None = 0, Wav = 1, Mp3 = 2, Aac = 4, Atrac = 8, Wma = 16, ... }
    MusicFormats appleSupported = MusicFormats.Wav | MusicFormats.Mp3 | MusicFormats.Aac;
    とすべき状況ですからねぇ。
    // 64bits でも足りないとなるとやっぱり列挙体風のクラスを作ることになりますけど。
記事No.9118 のレス /過去ログ21より / 関連記事表示
削除チェック/

■9223  Re[3]: enumの継承?
□投稿者/ ぼのぼの -(2007/10/22(Mon) 13:23:08)
    No9121 (未記入 さん) に返信
    > enumはSystem.Enumからの派生クラスであり、System.EnumはSystem.ValueTypeからの派生クラスです。
    > System.ValueTypeからの派生クラスは値型のクラス(構造体)なので.NETの多くからは継承できないはずです。
    > どうしても継承したい場合は普通のクラスに定数フィールドを並べて継承するしかなさそうですね。

    なるほど。C#でenumの継承が使えないことはわかりました。

    No9124 (Hongliang さん) に返信
    > 例がどうにも。
    > [Flags] enum MusicFormats { None = 0, Wav = 1, Mp3 = 2, Aac = 4, Atrac = 8, Wma = 16, ... }
    > MusicFormats appleSupported = MusicFormats.Wav | MusicFormats.Mp3 | MusicFormats.Aac;
    > とすべき状況ですからねぇ。
    > // 64bits でも足りないとなるとやっぱり列挙体風のクラスを作ることになりますけど。

    いやいや、待ってください。
    ビットのフラグで値を割り振るのは「重複可能な属性」の場合ではないですか?
    #例えばFileAttributesみたいな。
    これが、SupportedFormatという属性を表すならその通りなんですが、
    ここでは純粋にフォーマット形式を表す値として例に挙げたつもりでした。
    例えば、ConvertなりExportなりといったメソッドがあってその引数に使うような。

    No9125 (魔界の仮面弁士 さん) に返信
    > ■No9118 (ぼのぼの さん) に返信
    >>enumの場合似たような記述方法はあるのでしょうか?
    > 無いと思いますが、それができないと困るような状況に陥っているのでしょうか?

    あ、いや、別にそういうわけではないです(^^;
    ただの興味です。

    ただ、そういう状況を無理くり考えてみると。

    例えば、何らかの情報を保持するクラスがあって、
    public enum FileFormat {XML, Binary};
    virtual void Export(string fileName, FileFormat format)
    と定義されてたとします。

    で、A,B,Cという派生クラスがあって、
    CクラスだけCSV形式でのエクスポートにも対応したくなった、という場合。

    まぁCsvExportという別メソッドを作っちゃえばいいわけなんですが、
    FileFormatを継承して「CSV」だけ追加したenumを作って使えたら、
    ちょっと便利かな?などと思いまして。


    つまりですね、知りたかったのは、
    「『出力形式』みたいなものを表すクラスなり列挙体なり」に「継承」という概念を持ち込むことが、
    オブジェクト指向型言語での設計における一般的な指針に反するのか、
    それとも単に「C#ではenumの継承は無理よ」という言語仕様上の制約の結果に過ぎないのか。

    上記例のような設計が、少なくともC#でenumを使っては無理、てことで、
    じゃあ代わりにclassを使って同様のことを実現するのは、
    設計としては間違っていない?それとも普通はやらない?ということなのでした。
記事No.9118 のレス /過去ログ21より / 関連記事表示
削除チェック/

■9241  Re[4]: enumの継承?
□投稿者/ 未記入 -(2007/10/23(Tue) 00:53:31)
    No9223 (ぼのぼの さん) に返信
    > つまりですね、知りたかったのは、
    > 「『出力形式』みたいなものを表すクラスなり列挙体なり」に「継承」という概念を持ち込むことが、
    > オブジェクト指向型言語での設計における一般的な指針に反するのか、
    > それとも単に「C#ではenumの継承は無理よ」という言語仕様上の制約の結果に過ぎないのか。
    >
    > 上記例のような設計が、少なくともC#でenumを使っては無理、てことで、
    > じゃあ代わりにclassを使って同様のことを実現するのは、
    > 設計としては間違っていない?それとも普通はやらない?ということなのでした。

    僕はやらないかも。
    1つの列挙型として定義しておいて、使用不可のクラスに突っ込まれた時は引数が適切じゃないよ例外を発生させるとか。
記事No.9118 のレス /過去ログ21より / 関連記事表示
削除チェック/

■9243  Re[4]: enumの継承?
□投稿者/ 魔界の仮面弁士 -(2007/10/23(Tue) 12:51:10)
    No9223 (ぼのぼの さん) に返信
    > 「『出力形式』みたいなものを表すクラスなり列挙体なり」に「継承」という概念を持ち込むことが、
    > オブジェクト指向型言語での設計における一般的な指針に反するのか、
    > それとも単に「C#ではenumの継承は無理よ」という言語仕様上の制約の結果に過ぎないのか。

    エクスポート方法を拡張可能にするのであれば、データクラスに Export メソッドを
    付加して、そこに列挙体で方法を示す設計は避けた方が良いかと思います。
    エクスポート処理のみを担当するクラスを作り、そこにデータクラスを渡す設計の方が
    後の拡張がやりやすいかと思いますし。
    (その逆に、データクラスにエクスポートクラスを渡す設計でも良いですけれど)


    もし、出力形式を列挙体で示すにしても、それは enum を継承させようとするのではなく、
     void Export(string, FileFormat) // WAV, MP3用
     void Export(string, FileFormatMS) // WMA用
    のように、オーバーロードで解決した方が分かりやすいように思います。

    というのは、もしも FileFormat を 継承した FileFormatMS 列挙体を作れたとしても、その場合、
     void Export(string, FileFormat)
    を受け付けるメソッドに対して、
     obj.Export(file, MusicFormatMS.WAV); // 1
     obj.Export(file, MusicFormatMS.WMA); // 2
    のように呼び出したときに、どういった結果になるかが不明瞭になってしまうからです。
    Export メソッドの内部実装によって、結果が異なってしまうでしょうしね。

    (案1) FileFormatに無い値「WMA」が渡されたら、例外を発生させる。
     if(value == FileFormat.WAV) { WAV出力(); }
     } else if(value == FileFormat.MP3) { MP3出力(); }
     } else { throw InvalidEnumArgumentException(); }

    (案2) FileFormatに無い値「WMA」が渡されたら、WAV 扱いになる。
     if(value == FileFormat.MP3) { MP3出力(); }
     } else { WAV出力(); }

    (案3) FileFormatに無い値「WMA」が渡されたら、何もしない。
     if(value == FileFormat.WAV) { WAV出力(); }
     } else if(value == FileFormat.MP3) { MP3出力(); }
     } else { return; }
記事No.9118 のレス /過去ログ21より / 関連記事表示
削除チェック/



<< 0 >>

パスワード/

- Child Tree -