61

そのため、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列挙型を特定の種類として保存できることは知っていますが(リンク:http://msdn.microsoft.com/en-us/library/cc138362.aspx)、Typeその1つではありません。現在の選択肢は、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%完了している問題の解決策を複雑にしすぎていますか?

前もって感謝します!

4

7 に答える 7

93

列挙型のとしてそれを行うことはできませんが、属性で指定することはできます:

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) }
};

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

于 2012-06-13T05:51:31.167 に答える
19

これは、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();
于 2012-06-13T06:09:36.923 に答える
16

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

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

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));
}
于 2012-06-13T06:04:08.643 に答える
9

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

于 2012-06-13T05:51:57.170 に答える
2

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

于 2012-06-13T05:45:09.393 に答える
2

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

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

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

于 2012-06-13T10:17:45.723 に答える
0

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

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

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

于 2012-06-13T10:57:57.360 に答える