web-dev-qa-db-ja.com

Typeを( "typeof()"を使用して)列挙型に保存することは可能ですか?

そのため、XNA、C#4.0でゲームを作成しており、多くのPowerUp(コードではすべてクラス "PowerUp"から継承されています)を管理し、現在持っているPowerUpのバックエンド管理を処理する必要があります。列挙型、PowerupEffectType、PowerUpの各子クラスの値。最終的に、コードでPowerupEffectTypeからPowerupタイプ(クラスType、通常はtypeof([class name])で実現)に変換する必要があります。

これはグループプロジェクトであるため、PowerupEffectTypeの各値を対応するクラスTypeと可能な限り結合したいと思います。つまり、他のプログラマーがswitchステートメントを使用して手動で変換を行い、後で追加/拡張を確認することを期待するだけではありません。可能な限り少ない場所での変更を最小限に抑えます。これにはいくつかのオプションがありますが、これまでに発見した最善の方法は、ここで見つけたいくつかのヒントのおかげで、すべてを1つのswitchステートメント(必要なものの99%)に凝縮する列挙型疑似メソッドを作成することです。 http://msdn.Microsoft.com/en-us/library/bb383974.aspx

しかし、私はそれをさらに一歩進めようとしています-Typeenumに保存できますか?I列挙型を特定のタイプとして保存できることはわかっていますが(リンク: http://msdn.Microsoft.com/en-us/library/cc138362.aspx )、Typeはそうではありませんそれらの中の一つ。現在の選択肢は、byte、sbyte、short、ushort、int、uint、long、およびulongです。 Typeを上記のデータ型のいずれかに変換して元に戻すための実行可能な方法はありますか?

明確にするために、これは私ができることを望んでおり、私はそれを行う方法を探しています:

// (Assuming 'LightningPowerup', 'FirePowerup', and 'WaterPowerup' are
// all declared classes that inherit from a single base class)

public enum PowerupEffectType
{
    LIGHTNING = typeof(LightningPowerup),
    FIRE = typeof(FirePowerup),
    WATER = typeof(WaterPowerup)
}

これを行う方法はありますか、それともすでに99%完了している問題の解決策を複雑にしすぎていますか?

前もって感謝します!

61
KeithA45

列挙型のvalueとして実行することはできませんが、attributeで指定することはできます。

using System;
using System.Runtime.CompilerServices;

[AttributeUsage(AttributeTargets.Field)]
public class EffectTypeAttribute : Attribute
{
    public Type Type { get; private set; }

    public EffectTypeAttribute(Type type)
    {
        this.Type = type;
    }
}

public class LightningPowerup {}
public class FirePowerup {}
public class WaterPowerup {}

public enum PowerupEffectType
{
    [EffectType(typeof(LightningPowerup))]
    Lightning,
    [EffectType(typeof(FirePowerup))]
    Fire,
    [EffectType(typeof(WaterPowerup))]
    Water
}

その後、リフレクションを使用して、実行時にこれらの属性値を抽出できます。しかし、私は個人的に辞書を作成するだけです:

private static Dictionary<PowerupEffectType, Type> EffectTypeMapping =
    new Dictionary<PowerupEffectType, Type>
{
    { PowerupEffectType.Lightning, typeof(LightningPowerup) },
    { PowerupEffectType.Fire, typeof(FirePowerup) },
    { PowerupEffectType.Water, typeof(WaterPowerup) }
};

特別な属性は必要ありません。面倒なリフレクションコードで値を抽出する必要もありません。

93
Jon Skeet

これは、uが求めているものとはまったく異なります。 Jonの属性メソッドが最適だと思います。しかし、それを拡張メソッドでラップしてみませんか?

public Type GetPowerupEffectType(this PowerupEffectType powerEffect)
{
    switch (powerEffect)
    {
        case LIGHTNING:
            return typeof(LightningPowerup);
        case FIRE:
            return typeof(FirePowerup);
        case WATER:
            return typeof(WaterPowerup);
        default:
            return default(Type);
    }
}

そしてそれを呼んでください:

PowerupEffectType e = PowerupEffectType.WATER;
var t = e.GetPowerupEffectType();
18
nawfal

このようなものはどうですか?

列挙型で行う型安全性に加えて、型への暗黙の変換が得られます

public class PowerupEffectType
{
    private readonly Type _powerupType;

    public static implicit operator Type(PowerupEffectType powerupEffectType)
    {
        return powerupEffectType._powerupType;
    }

    private PowerupEffectType(Type powerupType)
    {
        _powerupType = powerupType;
    }

    public static readonly PowerupEffectType LIGHTNING = new PowerupEffectType(typeof(LightningPowerup));
    public static readonly PowerupEffectType FIRE = new PowerupEffectType(typeof(FirePowerup));
    public static readonly PowerupEffectType WATER = new PowerupEffectType(typeof(WaterPowerup));
}
16
mlorbetske

static Dictionary<PowerupEffectType, Powerup>を使用できます。それがあなたが探している「結婚」のようなものだと思います。簡単に列挙してアクセスできるようになります。

9
benjer3

Microsoftのドキュメントのように、数値タイプのみを使用できます。デフォルトでは、列挙型の各要素の基になる型はintです。前の例に示したように、コロンを使用して別の整数型を指定できます。可能なタイプの完全なリストについては、列挙型を参照してください。 参照:列挙型

2
Adil

申し訳ありませんが、私はこれに完全には従いません。あなたは実際に何を達成しようとしていますか。コードの抜粋を教えていただけますか?ここで継承を使用できない理由と、その型の継承では使用できない列挙型が何であるかはわかりません。問題ではなく解決策を提示しているように感じます。完全に間違っている可能性があります。このメタ情報をどのように使用する予定かを明確にしていただけますか?

私は混乱しています、あなたは型/クラスのインスタンスの型を教えてくれる何かを求めていますか?列挙型を使用して、言う各タイプのタイプのリストを格納できますが、なぜそうしたいのですか?他のプログラマーにswitchステートメントを使用させたくないとおっしゃっていますが、型の列挙に型情報を格納することでどのようなメリットが得られるのかわかりません。すべてのインスタンスは、それがどのタイプで、何ができるかを知っています。

タイプ情報はどうしますか?型がすべて基本型を継承している場合は、おそらく、特別な場合の処理​​のためにabstractメソッドで指定できる共通の機能を持っているか、何もすることがない場合はNull Objectを返します。 (または、何もしないでください)。このように、新しいクラスを追加することを心配する必要はありません-それらは必要な振る舞いをしなければならないからです。 Enumsは避けようとしますが、実際に任意の値の固定セットを列挙している場合は、柔軟性がありません。 Enumsを維持する必要がありますが、これは(実際には)非常に困難です。

2
nicodemus13

実際、依存性注入フレームワークを見てみたいと思うかもしれません。

他の開発者にさまざまなコンポーネントで作業させようとしていて、それらすべてをコードベースの1つの中央の場所に統合しようとしているようです。

注目すべきいくつかのプロジェクト:

0
Wil