【问题标题】:Should I use Int32[,] or System.Drawing.Point when all I want is the x,y coordinates?当我想要的只是 x,y 坐标时,我应该使用 Int32[,] 还是 System.Drawing.Point?
【发布时间】:2016-03-09 13:11:39
【问题描述】:

我正在构建一个应用程序,让我可以从我的 PC 控制我的 Android 设备。它运行得很好,所以现在我想开始清理我的代码以供发布。我正在尝试清理我不需要的解决方案引用,因此我查看了用于实现Point 类的using System.Drawing;。问题是,如果我切换到使用二维 Int32 数组,我真的不需要它。

所以我可以:new Int32[,] {{200, 300}}; 而不是 new Point(200, 300); 并完全摆脱 System.Drawing 命名空间。问题是:这真的重要吗?通过保留System.Drawing 命名空间,我是否真的在我的应用程序中引入了膨胀? Int32[,] 是否更轻量级?

或者,我是否应该不使用任何一个,只跟踪单个 Int32 变量中的 x,y 坐标?

编辑:我摆脱了我写的原始想法:Int32[200, 300] 并用new Int32[,] {{200, 300}}; 替换它,因为正如@Martin Mulder 指出的Int32[200, 300]“创建一个二维数组60000个整数,都是0。”

EDIT2:所以我很笨。首先,我试图通过使用多维数组来幻想太多。彻头彻尾的愚蠢。其次,我接受了使用结构的建议,并且一切正常,所以感谢前四个答案;他们每个人都是正确的。但是,毕竟,我最终无法删除 System.Drawing 引用,因为我正在开发一个 WinForms 应用程序,而 System.Drawing 正在应用程序的设计器中使用!我想我可以进一步重构它,但我把它的大小缩小到了 13KB,所以它已经足够好了。谢谢大家!

【问题讨论】:

  • 为什么不实现自己的不依赖 System.Drawing 的 Point 结构。我希望我误解了您使用 int 数组来跟踪分辨率...
  • 嗯,重点(呵呵)是除了来自“Point”类的两个整数之外,我不需要任何东西。 'struct' 是否比 'Int32[,]' 或两个 Int32's 更轻量级?
  • 我会忘记数组的想法。这里没有任何类型的数组的上下文。一个结构本质上是将两个ints 组合成一个值,因此它相对等同于两个int 的想法。
  • 您可以使用Tuple<int, int> 来存储它,而不是数组或Point

标签: c# winforms multidimensional-array system.drawing


【解决方案1】:

仅通过引用库就不会“嵌入”到您的应用程序中。但是,如果 Point 类真的是你所需要的,你可以删除引用并实现你自己的 Point 结构。这可能比int 数组更易于阅读。

Int32[,] 是不同的东西。它是一个二维数组,而不是一对两个 int 值。使用它会让事情变得更糟。

可以使用Tuple<int, int>,但我会去创建你自己的结构。


正如一些人在这里提出的实施建议。所以只需包装你的两个整数,我就用这个:

public class MyPoint
{
    public int X;
    public int Y;
} 

仅在需要时添加所有其他功能。

【讨论】:

  • 已经好几年了,但我用 x,y 实现了一个结构
【解决方案2】:

只需创建您自己的:

public struct Point : IEquatable<Point>
{
  private int _x;
  private int _y;
  public int X
  {
    get { return _x; }
    set { _x = value; }
  }
  public int Y
  {
    get { return _y; }
    set { _y = value; }
  }
  public Point(int x, int y)
  {
    _x = x;
    _y = y;
  }
  public bool Equals(Point other)
  {
    return X == other.X && Y == other.Y;
  }
  public override bool Equals(object other)
  {
    return other is Point && Equals((Point)other);
  }
  public int GetHashCode()
  {
    return unchecked(X * 1021 + Y);
  }
}

更好的是,使其不可变(使字段 readonly 并删除设置器),但如果您依赖于您在问题中考虑的两个选项的可变性,那么这将需要更多的更改你如何做事。但实际上,不变性是我们要走的路。

【讨论】:

  • 你能告诉我为什么我需要实现IEquatable吗?我真的只想要两个Int32
  • 你不需要,但在结构上实现IEquatable&lt;T&gt; 总是一个好主意(除非你有其他理由,否则这似乎很自然地是一个结构),因为默认相等相对昂贵。当然,如果你从不比较两点,那也没关系。
  • @MartinMulder 严格来说,从 ValueType 继承的 Equals() 会正确完成这项工作,但它会通过反射,这比它需要的成本更高。
【解决方案3】:

您的建议非常不明智:。

  • new Point(200, 300) 使用两个整数创建一个新点:X 和 Y 属性,值为 200 和 300。

  • new Int32[200,300]创建一个包含60000个整数的二维数组,所有整数都是0。

  • (编辑后)new Int32[,] {{200, 300}} 还创建了一个二维数组,这次包含 2 个整数。要检索第一个值 (200),您可以像这样访问它:array[0,0] 和第二个值 (300),例如 array[0,1]。第二个维度不是必需的、不需要的或不需要的。

如果您想摆脱对库的引用,还有其他一些建议:

  1. new Int32[] {200, 300} 创建一个由两个整数组成的一维数组,其值为 200 和 300。您可以使用 array[0]array[1] 访问它们。
  2. 正如 Ron Beyer 所建议的,您可以使用 Tuple&lt;int, int&gt;
  3. 创建您自己的Point-struct(由 Jon Hanna 指出)。它使您的应用程序更大一些,但是您阻止了引用,并且阻止了库 System.Drawing 加载到内存中。

如果我想删除该引用,我会选择最后一个选项,因为它更清楚我在做什么(点比 Int32 数组或元组更具可读性)。解决方案 2 和 3 比解决方案 1 稍快。

【讨论】:

  • 这不是真的“不可能”,理论上(而且不明智)您可以使用每个维度的上限作为“点”。
  • @Ron Beyer:更正! :)
  • 我明白你的意思了(!)。我想对我所学到的多维数组感兴趣,但完全混淆了我对一个普通的无聊 Int32[] 的想法。
【解决方案4】:

正如@Glorin Oakenfoot 所说,您应该实现自己的 Point 类。这是一个例子:

public class MyPoint // Give it a unique name to avoid collisions
{
   public int X { get; set; }
   public int Y { get; set; }
   public MyPoint() {} // Default constructor allows you to use object initialization.
   public MyPoint(int x, int y) { X = x, Y = y }
}

【讨论】:

  • 一个班级对这个有点强硬,不是吗?
  • @Kristopher 一点也不。很清楚。这才是重点。首先编写代码以提高可读性/可维护性,然后在需要时优化性能。
  • 话虽如此,我个人会选择一个结构,因为两个整数结构将是 8 个字节,这似乎比对象开销更有效,而且在上下文中不太可能永远需要取消设置/为空。不过,这可能会让人毛骨悚然。
  • 一个结构就可以了。
猜你喜欢
  • 1970-01-01
  • 2010-09-08
  • 1970-01-01
  • 2011-07-08
  • 1970-01-01
  • 2023-03-06
  • 2019-05-24
  • 1970-01-01
  • 2011-09-03
相关资源
最近更新 更多