0

as 演算子の使い方を学んでいます。私の目標は、次のことができるオプション ウィンドウ (非ウィンドウ フォーム) を作成することでした。

オプションを追加する (if ステートメントを使用してメニュー項目を追加する場合に備えて、柔軟性を高めるため) テキスト、テクスチャ、またはクラスを表示できる (クラスの draw 関数を使用) ホストの GameState を通じて制御される

アイテムが選択されていることを示すオプションをまだ追加していません。完全な作品を投稿していないことをお詫びします。また、コードをまだリージョンに分類していません。またすみません!

私のコード (特に draw 関数) は、パフォーマンスと可読性 (非スパゲッティ コード) の観点から、 is および as 演算子を適切に使用していますか?

public class OptionWindow : DrawableGameComponent
{
    public Dictionary<int, Option> options;
    int selectedOption;
    bool windowLoops;
    Rectangle drawRectangle;
    int spacer;
    int totalItemHeight;
    SpriteFont sf;
    SpriteBatch sb;

    public Rectangle DrawRectangle
    {
        get { return drawRectangle; }
        set { drawRectangle = value; }
    }

    public int SelectedOption
    {
        get { return selectedOption; }
        set
        {
            if (windowLoops)
            {
                if (selectedOption >= options.Count())
                    selectedOption = 0;
                if (selectedOption < 0)
                    selectedOption = options.Count() - 1;
            }
            else
            {
                if (selectedOption >= options.Count())
                    selectedOption = options.Count() - 1;
                if (selectedOption < 0)
                    selectedOption = 0;
            }
        }
    }

    public OptionWindow(Game game, bool windowLoops, SpriteFont sf, Rectangle drawRectangle)
        : base(game)
    {
        options = new Dictionary<int, Option>();
        this.windowLoops = windowLoops;
        this.sf = sf;
        DrawRectangle = new Rectangle(drawRectangle.X, drawRectangle.Y, drawRectangle.Width, drawRectangle.Height);
    }
    public void Add(object option, bool selectable, bool defaultSelection, int height)
    {
        options.Add(options.Count(), new Option(selectable, option, height));
        if (defaultSelection)
            SelectedOption = options.Count() - 1;
        UpdatePositions();
    }
    public void UpdatePositions()
    {
        UpdateTotalItemHeight();
        if (options.Count() - 1 != 0)
            spacer = (drawRectangle.Height - totalItemHeight) / (options.Count() - 1);
        for (int i = 0; i < options.Count(); i++)
        {
            if (i == 0)
                options[i].Position = new Vector2(drawRectangle.X, drawRectangle.Y);
            else
            {
                options[i].Position = new Vector2(
                    drawRectangle.X,
                    options[i - 1].Position.Y + options[i - 1].Height + spacer);
            }
        }
    }
    public void UpdateTotalItemHeight()
    {
        totalItemHeight = 0;
        for (int i = 0; i < options.Count(); i++)
        {
            totalItemHeight += options[i].Height;
        }
    }
    protected override void LoadContent()
    {
        sb = new SpriteBatch(GraphicsDevice);
        base.LoadContent();
    }
    public override void Draw(GameTime gameTime)
    {
        for (int i = 0; i < options.Count(); i++)
        {
            if (options[i].OptionObject is string)
                sb.DrawString(sf, options[i].OptionObject as string, options[i].Position, Color.White);
            if (options[i].OptionObject is Texture2D)
                sb.Draw(options[i].OptionObject as Texture2D,
                    new Rectangle(
                        (int)options[i].Position.X,
                        (int)options[i].Position.Y,
                        options[i].Height,
                        (options[i].Height / (options[i].OptionObject as Texture2D).Height) * (options[i].OptionObject as Texture2D).Width),
                        Color.White);
            if (options[i].OptionObject is DisplayObject)
                (options[i].OptionObject as DisplayObject).Draw(gameTime);
        }
        base.Draw(gameTime);
    }
}

public class Option
{
    bool selectable;
    object optionObject;
    int height;
    Vector2 position;
    public bool Selectable
    { 
        get { return selectable; }
        set { selectable = value; }
    }
    public object OptionObject
    {
        get { return optionObject; }
        set { optionObject = value; }
    }
    public int Height
    {
        get { return height; }
        set { height = value; }
    }
    public Vector2 Position
    {
        get { return position; }
        set { position = value; }
    }
    public Option(bool selectable, object option, int height)
    {
        Selectable = selectable;
        OptionObject = option;
        Height = height;
    }
}
4

1 に答える 1

4

isand then を使用することはお勧めできませんas。通常の方法は、次のいずれかになります。

  • 使用isするだけです(その後のキャストなしで型を知りたいだけの場合)
  • の結果をas変数に代入し、その変数が (そうでない) かどうかを確認しますnull

コード分​​析ツールFxCopisを使用すると、コード内で と を使用している箇所を見つけてas、パフォーマンスの問題のために警告を発することができます。

ただし、より良いアプローチは、OptionObjectプロパティをメソッドを持つ抽象クラスとして宣言することであることに注意してくださいDraw。次に、文字列のサブクラスをインスタンス用に 1 つ、Texture2Dインスタンス用にもう 1つ派生させ、メソッドをDisplayObject呼び出すだけです。これにより、どの実際の描画操作を実行するかの決定は、フレームワークの組み込みポリモーフィズム機能に委ねられます。DrawOptionWindow.Draw

于 2012-09-12T06:47:01.460 に答える