2016-04-28 133 views
0

将有一个几何形状类实现看起来是这样的:如何将Geometry.Parse的几何结果与Geometry.Empty进行比较?

private readonly IShapeModel _shape; 

    public Shape(IShapeModel shape) : base(shape) 
    { 
     _shape = shape; 
    } 

    /// <summary> 
    /// Specific geometry data of the shape 
    /// </summary> 
    public string GeometryData => _shape.GeometryData; 

    /// <summary> 
    /// Returns the <see cref="Geometry"/> for this shape 
    /// </summary> 
    public Geometry Geometry => Geometry.Parse(GeometryData); 

正如你可以看到我提供了一个模型的形状,并使其返回几何对象与几何提供的标准解析方法。

该代码完美工作,并在未设置GeometryData时返回空几何。

现在我想这样的事情来测试它:

[TestMethod] 
    public void AccessGeometryPropertyWithNoGeometryDataSetShouldReturnEmpty() 
    { 
     var shape = new TestShapeModel {GeometryData = null}; 
     _shapeViewModel = new Shape(shape); 
     var expected = Geometry.Empty; 
     var actual = _shapeViewModel.Geometry; 
     Assert.AreEqual(expected, actual); 
    } 

虽然问题是Geometry.Empty似乎返回一个新的实例,它是不等于解析的实例的结果。

尽管两个对象都是相同的。我得到这个结果: 附加信息:Assert.AreEqual失败。预计:<>。实际:<>。

当我想出了这一点:

[TestMethod] 
    public void AccessGeometryPropertyWithNoGeometryDataSetShouldReturnEmpty() 
    { 
     var shape = new TestShapeModel {GeometryData = null}; 
     _shapeViewModel = new Shape(shape); 
     Assert.IsTrue(IsEmptyGeometry(_shapeViewModel.Geometry)); 
    } 

    /// <summary> 
    /// Check if Geometry is empty by comparing Empty Bounds. 
    /// </summary> 
    private static bool IsEmptyGeometry(Geometry geometry) 
    { 
     var result = false; 
     var expected = Geometry.Empty; 
     if (geometry != null) 
     { 
      result = (geometry.Bounds == expected.Bounds); 
     } 
     return result; 
    } 

是否有更好的方法来解决这个问题?我希望框架中的某些东西能够与Geometry.Empty进行比较,而不必重写Equals或者实现上面的代码。

+2

['Geometry.IsEmpty()'](https://msdn.microsoft.com /en-us/library/system.windows.media.geometry.isempty(v=vs.110).aspx)? –

回答

1

如果几何图形不是由你来实现在所有的,你可以把你的IsEmptyGeometry方法,使它的扩展方法,并使用它以“好看”的方式进行声明。的

public static class GeometryExtensions 
{ 
    public static bool IsEmpty(this Geometry geometry) 
    { 
     var result = false; 
     var expected = Geometry.Empty; 

     if (geometry != null) 
     { 
      result = (geometry.Bounds == expected.Bounds); 
     } 

     return result; 
    } 
} 

然后不要做这样的:

[TestMethod] 
    public void TestEmptyGeometry() 
    { 
     var shape = new TestShapeModel { GeometryData = null }; 
     _shapeViewModel = new Shape(shape); 
     var expected = Geometry.Empty; 
     var actual = _shapeViewModel.Geometry; 
     Assert.AreEqual(expected, actual); 
    } 

你可以这样做:

[TestMethod] 
    public void TestEmptyGeometry() 
    { 
     var shape = new TestShapeModel { GeometryData = null }; 
     _shapeViewModel = new Shape(shape); 
     var actual = _shapeViewModel.Geometry; 
     Assert.IsTrue(actual.IsEmpty()); 
    } 
+0

使用扩展方法确实使其更加优雅。在这种情况下,我可能会考虑更改/删除空检查。我会投这个答案是最好的解决方案。 –

+0

奇怪的是,我完全忽略了像Damien_The_Unbeliever提到的框架内已经存在IsEmpty()方法的事实。它最终使这个解决方案过时了。 –

0

Assert.Equals使用等于对象之间的比较,因此您必须重写System.Object的Equals方法,以便通过比较两个Geometry对象来使其工作。我不知道你的几何实现,所以我会假设基本的工作如何通过你的解释。

我假设什么让一个几何像其他人一样是他们有相同的界限。在你的情况下,它必须比这更复杂,所以在我的例子中考虑它。

下面是几何类中要做的事情。

public class Geometry 
{ 
    // I don't know what is the implementation of bounds, so 
    // I'm just assuming that is something comparable here. 
    public Rectangle Bounds { get; set; } 

    // Here's your definition of Geometry.Empty, from what I understood. 
    public static Geometry Empty 
    { 
     get 
     { 
      return new Geometry { Bounds = new Rectangle(0, 0, 0, 0) }; 
     } 
    } 

    // Here is the key: you must override the default operators of equality 
    // and difference to make comparations to work, because internally it will 
    // use them. 
    public static bool operator ==(Geometry left, Geometry right) 
    { 
     if (left == null && right == null) 
     { 
      return true; 
     } 

     if (left != null && right != null) 
     { 
      return left.Bounds == right.Bounds; 
     } 

     return false; 
    } 

    public static bool operator !=(Geometry left, Geometry right) 
    { 
     if (left == null && right == null) 
     { 
      return false; 
     } 

     if (left != null && right != null) 
     { 
      return left.Bounds != right.Bounds; 
     } 

     return true; 
    } 

    // I recommend you to override Equals method of 
    // System.Object too. For Assert.AreEqual to work, 
    // actually this method will be used. 
    public override bool Equals(object obj) 
    { 
     var objAsGeometry = obj as Geometry; 

     if (obj == null) 
     { 
      return false; 
     } 

     return objAsGeometry.Bounds == this.Bounds; 
    } 

    // GetHashCode is used in some types of comparations too, 
    // altough not in your case with Assert.AreEqual. 
    // If you want to make a fully comparable object, 
    // be sure to override it too, with all conditions used 
    // to compare one Geometry object with other. 
    public override int GetHashCode() 
    { 
     return Bounds.GetHashCode(); 
    } 
} 

通过这样做,比较两个Geometry.Empty对象测试必须通过:

[TestClass] 
public class GeometryTests 
{ 
    [TestMethod] 
    public void TestTwoEmptyGeometries() 
    { 
     var geometry1 = Geometry.Empty; 
     var geometry2 = Geometry.Empty; 

     // Pass 
     Assert.AreEqual(geometry1, geometry2); 
    } 
} 
+0

我怀疑他们在谈论[this](https://msdn.microsoft.com/en-us/library/system.windows.media.geometry(v = vs.110).aspx)'Geometry'类,即不是他们自己的一个。 –

+0

那么,如果他没有实现Geometry,那么Assert.Equals根本就不起作用,因为类本身与该方法没有可比性。然后,我会建议采用这种方法IsEmpty并使其成为扩展方法,因此他可以调用Geometry.IsEmpty()来代替。 – Ismael

相关问题