C# 在DrawableGameComponent中这样有效地使用Is和as操作符吗?

C# 在DrawableGameComponent中这样有效地使用Is和as操作符吗?,c#,menu,xna,C#,Menu,Xna,我正在学习使用as操作符,我的目标是创建一个选项窗口(非windows窗体),它可以: 添加了选项(为了灵活性,如果我想使用if语句添加菜单项) 能够显示文本、纹理或类(使用类绘制功能) 通过主机游戏状态进行控制 我仍然没有添加指示项目已被选中的选项,很抱歉没有发布完整的作品。我还没有将代码分为多个区域。再次抱歉 从性能和可读性(非意大利面代码)的角度来看,我的代码(特别是绘图函数)是否正确地使用了Is和as运算符 public class OptionWindow : DrawableGame

我正在学习使用as操作符,我的目标是创建一个选项窗口(非windows窗体),它可以:

添加了选项(为了灵活性,如果我想使用if语句添加菜单项) 能够显示文本、纹理或类(使用类绘制功能) 通过主机游戏状态进行控制

我仍然没有添加指示项目已被选中的选项,很抱歉没有发布完整的作品。我还没有将代码分为多个区域。再次抱歉

从性能和可读性(非意大利面代码)的角度来看,我的代码(特别是绘图函数)是否正确地使用了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;
    }
}
公共类选项窗口:DrawableGameComponent
{
公共词典选项;
int选择选项;
布尔窗环;
矩形绘制矩形;
内间隔;
整数总高度;
斯普里特丰;
鞭打某人;
公共矩形绘图矩形
{
获取{return drawRectangle;}
设置{drawRectangle=value;}
}
公共整数选择选项
{
获取{return selectedOption;}
设置
{
if(窗口循环)
{
if(selectedOption>=options.Count())
选择选项=0;
如果(选择选项<0)
selectedOption=options.Count()-1;
}
其他的
{
if(selectedOption>=options.Count())
selectedOption=options.Count()-1;
如果(选择选项<0)
选择选项=0;
}
}
}
公共选项窗口(游戏、bool windowLoops、SpriteFont sf、矩形draw矩形)
:基地(游戏)
{
选项=新字典();
this.windowLoops=windowLoops;
this.sf=sf;
DrawRectangle=新矩形(DrawRectangle.X,DrawRectangle.Y,DrawRectangle.Width,DrawRectangle.Height);
}
公共无效添加(对象选项、布尔可选、布尔默认选择、整数高度)
{
添加(options.Count(),新选项(可选,选项,高度));
如果(默认选择)
SelectedOption=options.Count()-1;
更新位置();
}
公共无效更新位置()
{
UpdateTotalItemHeight();
if(options.Count()-1!=0)
间隔符=(drawRectangle.Height-totalItemHeight)/(options.Count()-1);
对于(int i=0;i
不建议使用
is
然后再使用
as
。通常的方法是执行以下任一操作:

  • 只需使用
    is
    (如果您只想知道类型而不需要后续强制转换)
  • 的结果指定为一个变量,并检查该变量是否为空
代码分析工具可帮助您找到代码中使用
is
as
的任何点,并因性能问题向您发出警告

但是请注意,更好的方法可能是使用
Draw
方法将
OptionObject
属性声明为某个抽象类。然后可以为字符串派生一个子类,一个用于
Texture2D
实例,另一个用于
DisplayObject
实例,只需在
选项窗口中调用
Draw
。Draw
方法。这将决定要执行的实际绘图操作将取决于框架的内置多态性功能。

这永远不是adv