我使用XNA,我做的很多事情之一是传递数据作为Vector2s。现在,XNA中的很多对象(例如图形设备等),inste3ad包含一个告诉你视口大小的Vector2,它们提供了单独的Width和Height方法。有没有办法向他们添加一个Vector2属性,这样我可以获得该数据,而无需在每次需要时手动构建一个新的vector2?我想我想要的是“扩展属性”...
答案 0 :(得分:2)
Vector2是一个值类型......老实说,你不必太担心创建新实例,因为它们是在堆栈上创建的。每次你可以使用.Vector属性,无论如何它都会创建一个新实例。
您不必担心它,因为值类型不会调用垃圾收集器。因此,尝试实例化一次的最大原因是无效(即GC)。
就是说,对于像Matrix这样的大型结构,您可能需要考虑将它们传递给参数以避免堆栈上的新分配。
答案 1 :(得分:2)
就效率而言,最好只使用“宽度”和“高度”属性随时随地执行任何操作。不要忘记优化的第一条规则:don't do it。
包装类的想法是一个很好的解决方案,但我只是想把全局可转换结构放在那里。我使用这样的东西来消除担心vector-> point和point->向量转换(至少在调试期间):
[DebuggerDisplay("{value}")]
public struct PointyVector
{
Vector2 value;
//Constructors:
public PointyVector(System.Drawing.Point point)
{
value = new Vector2(point.X, point.Y);
}
public PointyVector(Point point)
{
value = new Vector2(point.X, point.Y);
}
public PointyVector(Vector2 vector)
{
value = new Vector2(vector.X, vector.Y);
}
//Implicit conversion operators:
public static implicit operator PointyVector(Vector2 vector)
{
return new PointyVector(vector);
}
public static implicit operator PointyVector(System.Drawing.Point point)
{
return new PointyVector(point);
}
public static implicit operator PointyVector(Point point)
{
return new PointyVector(point);
}
public static implicit operator Vector2(PointyVector vector)
{
return vector.value;
}
public static implicit operator Point(PointyVector vector)
{
return new Point((int)vector.X, (int)vector.Y);
}
}
这种结构,在Vector2和Point之间增加了一些二元运算符,使得Xna中的矢量/点内容变得更加简单,但它也会导致投射歧义,舍入误差,截断损失以及所有其他乐趣与数字转换相关的问题。所有这些问题都可以通过显式转换轻松解决,但请注意,如果在使用此结构时看到“怪异数字”,则可能是转换期间的精度损失。
答案 2 :(得分:1)
不支持扩展属性,但您仍然可以编写扩展方法:
class ExtensionMethods
{
public static Vector2 GetViewSize(this GraphicsDevice device)
{
return new Vector2(device.Viewport.Width, device.Viewport.Height);
}
}
答案 3 :(得分:1)
你可以使用Michael的方法,但实际上每次都会构建一个新的Vector2。如果你真的只想创建一次Vector2,你可以包装你想要的类,并提供你自己的Vector2属性:
public class GraphicsDeviceWrapper
{
private Vector2 vector;
public GraphicsDeviceWrapper(GraphicsDevice device)
{
this.vector = new Vector2(device.Viewport.Width, device.Viewport.Height);
this.Device = device;
}
public Vector2 Vector
{
get{return this.vector;}
}
public GraphicsDevice Device
{
get; private set
}
}