我正在学习使用as运算符,我的目标是创建一个选项窗口(非窗口窗体),它可以:
添加了选项(为了灵活性,以防我想使用if语句添加菜单项) 能够显示文本,纹理或类(使用类绘制功能) 通过主机GameState控制
我仍然没有添加指示项目被选中的选项,对于没有发布完整作品表示歉意。我还没有将代码分类到区域。对不起!
从性能和可读性(非意大利面条代码)的角度来看,我的代码(尤其是绘图函数)是否正确使用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;
}
}
答案 0 :(得分:4)
永远不建议使用is
然后使用as
。通常的方法是下列之一:
is
(如果您只是想知道没有后续投射的类型)as
的结果分配给变量并检查该变量是否为({1}} 代码分析工具FxCop可帮助您找到代码中使用null
然后is
的任何位置,并因性能问题向您发出警告。
但是请注意,更好的方法可能是将as
属性声明为具有OptionObject
方法的抽象类。然后,您可以为字符串派生一个子类,一个用于Draw
个实例,另一个用于Texture2D
个实例,只需在DisplayObject
方法中调用Draw
即可。这将决定实际的绘图操作执行到框架的内置多态性功能。