我在我的项目中使用GeoJSON.NET库。在某些时候,我需要更新我的数据库中的一个特性。作为其中的一部分,我需要访问上述特性的坐标,以便将这些信息也存储在数据库中。但是,从GitHub上的源代码来看,这个特性类具有IGeometryObject的几何属性:
public IGeometryObject Geometry { get; set; }根据GeoJSON规范,存在多个“形状”,如“多边形”、“圆”、“点”等,这些特定形状已在GeoJSON.NET项目中建立。
在这些具体的类型中,我实际上可以挖掘并访问不同的坐标。
目前,我有以下几点:
public int CreateFeature(Feature feature)
{
int featureId = 0;
var coordinatesDt = new DataTable();
coordinatesDt.Columns.Add("Latitude");
coordinatesDt.Columns.Add("Longitude");
//we are loading a datatable with the coordinates. This gets passed to a SQL server stored procedure as a single parameters to insert
//all the nodes.
LineString lineString = ((Polygon)feature.Geometry).Coordinates[0];
foreach (var coordinate in lineString.Coordinates)
{
var row = coordinatesDt.NewRow();
row["Latitude"] = ((GeographicPosition)coordinate).Latitude;
row["Longitude"] = ((GeographicPosition) coordinate).Longitude;
coordinatesDt.Rows.Add(row);
}
using (SqlConnection conn = new SqlConnection(_smmConnectionString))
using (SqlCommand cmd = new SqlCommand("dbo.MyProc", conn))
{
//set up params, set up TVP and execute...
}
return featureId;
}下面是Polygon类的一个片段:
public List<LineString> Coordinates { get; set; }因此,在我的代码中,我实际上是在对多边形进行显式向下转换,因为我需要找到Polygon类的坐标成员。我知道我这样做是安全的,因为这是我在应用程序中使用的唯一的“类型”形状,尽管我知道这不一定是最佳实践。然而,在未来,如果我们使用其他类型,这将完全打破。我可以使用"is“或”as“来实现类型检查,但这仍然不能使我摆脱不得不向下转换的概念。
所以我的问题是什么是最好的方法去做这件事?我读过关于为什么要使用接口和所有这些作为成员和/或参数,以及必须做一个明确的向下转换是“通常”不好的做法,并遵循糟糕的设计模式.除了罕见的病例。那么,我是陷入了“罕见的案例”,还是有更好的方法来解决这一问题?
发布于 2016-06-10 15:31:43
基于GeoJSON.NET API,我认为您确实陷入了这些“罕见的情况”之一。您有几个处理此问题的选项:
if (shape is Polygon) ProcessShape((Polygon)shape);,并将其分派给特定于形状的方法。备选方案1的示例代码:
switch (shape.Type)
{
case GeoJSONObjectType.Polygon:
ProcessShape((Polygon)shape);
break;
// additional shape support here...
}备选方案3的示例代码:
// Add an AcceptVisitor method to the IGeometryObject interface:
public interface IGeometryObject
{
GeoJSONObjectType Type { get; }
void AcceptVisitor(IShapeProcessor visitor);
}
// Update each concrete shape class to include the new AcceptVisitor method:
public void AcceptVisitor(IShapeProcessor visitor)
{
visitor.ProcessShape(this);
}
// Add an IShapeProcessor interface to the GeoJSON.NET project:
public interface IShapeProcessor
{
void ProcessShape(Polygon shape);
void ProcessShape(MultiPoint shape);
void ProcessShape(LineString shape);
// ...additional shape support...
}
// Update your existing class to implement the IShapeProcessor interface,
// and then change your code to do something like:
feature.Geometry.AcceptVisitor(this);...and如果你选择3,在GitHub上提交一个拉请求,这样每个人都可以从你的改进中受益!
发布于 2016-06-10 15:17:28
因此,您已经决定需要访问无法更改的某人接口的内部实现细节。
那么你真的别无选择,只能承担未来维护的费用。是的,你有一个罕见的案子..。
为了将成本降到最低,我强烈建议您将所有危险的代码包装在一个在发布的接口上操作的助手类中,这样您就不会将它与您自己的业务逻辑混在一起,并清楚地看到您将来需要在哪里进行更改。
https://stackoverflow.com/questions/37751507
复制相似问题