我有三个不同的类:
Task
Order
Transmission
每个类都有不同类型的属性。此外,还可以附加由自定义字段表示的数据(由IField数组实现,其中IField可以是文本字段或列表字段)。每个自定义字段都有一个名称,表示附加数据属性的名称。
我需要在每个班级之间进行转换:
Task -> Order
Order -> Transmission
Transmission -> Task
Transmission -> Order
Order -> Task
Task -> Transmission
为此我创建了:
DataObject
”,其中包含属性名称和对象的字典作为其值。每个类(Task,Order,Transmission)实现IDataShare接口:
public interface IDataShare
{
DataObject ToDataObject();
void FromDataObject(DataObject data);
}
例如,具有以下属性的任务对象:
WorkerId:5
CustomerId:7
VehicleId:null
StartDate:null
并使用以下自定义字段:
Subcontractor: {listId:5, Value:4} (this is list field)
delivery Note: "abc" (this is text field)
将转换为以下字典:
{"WorkerId", 5}
{"CustomerId", 7}
{"VehicleId", null}
{"StartDate", null}
{"Subcontractor", {listId:5, Value:4}}
{"delivery Note", "abc"}
字符串键“WorkerId”,“CustomerId”,“VehicleId”,“StartDate”取自包含字符串consts的静态类,其中“Subcontractor”和“deliveryNote”是用户添加的自定义字段的名称(I不知道用户可能添加哪些字段,所以我只使用字段名称)。 当我使用DataObject填充对象时,我必须验证属性的名称是否与键的名称相同,并验证值是否正确(字符串不能插入long)。 此外,自定义列表字段(子转换程序)不能只将itemId作为值,因为当我必须验证对象中自定义字段的listId与DataObject中customField的listId相同时。
我知道值的类型有很多问题。如果“X as Y”语句的陈述,我总是必须使用“X is Y”。另外,我必须记住在实现IDataShare接口时如何存储值的类型,这使得工作更加困难。
任何人都可以帮我思考一下我可以添加到从对象到DataObject的转换过程中的约束吗?任何人都可以帮我改进这种转换对象的方法吗?
谢谢!
更新
我想解释一点。我最大的问题是有几种方法来翻译每个属性/自定义字段,所以我需要记住DataObject中值的类型。例如,在Transmission类中,我有VehicleId属性。我想将具有名称“VehicleId”的自定义字段的Task对象转换为Transmission。我想要的是Task的自定义字段VehicleId的值将被转换为Transmission的VehicleId属性。但是,因为它是自定义字段 - 正如我之前写的那样 - 有一种方法可以存储基于list: {listId:5, Value:4}
的自定义字段。现在,在转换过程(传输中的FromDataObject)中,如果DataObject具有“VehicleId”键,我必须检查值是否为long(车辆ID为属性)或IListField(车辆ID为自定义列表字段)。
那些类型检查确实搞得一团糟。
答案 0 :(得分:1)
那么,如果您之间转换的课程数量实际上与您所说的有限,我可以建议您为您的课程编写演员操作员吗?
http://msdn.microsoft.com/en-us/library/xhbhezf4%28v=VS.100%29.aspx
似乎你在转换中投入的逻辑量足以保证这样的东西。 另一方面,似乎在不同对象中使用了一组基本字段,而您只是将它们填充到无类型字典中。如果这些字段在所有类型中都是通用的,您是否可以使用转换为强类型公共对象? 这也引出了一个问题:你能使用一个共同的基类对象吗?
如果您有修改任务,订单和传输定义的选项,我会再次查看它们。这种情况看起来像是“代码味道”。
答案 1 :(得分:0)
如果我理解正确ToDataObject
基本上是序列化程序,FromDataObject
是反序列化程序。如果这些对象包含的数据类型兼容,那么将其序列化为无类型数据的行为似乎就是问题的根源。为什么这样做,而不是仅仅保持原始格式的数据?
如果您需要使用适配器,因为由于某种原因无法解析的对象之间存在不兼容性,我认为您可以创建一个至少将数据保留在其本机结构中而不是将所有内容序列化为一个字符串。 C#中的字典可以包含任何内容,至少您可以使用Dictionary<string,object>
。
还不清楚所有这些验证的内容 - 如果要映射相同数据类型的属性,为什么数据会不兼容?例如。假设这是一个内部过程,在什么情况下(例如)来自一个对象的string
试图被分配给另一个对象中的long
?似乎只有在数据在一个对象中强类型而在另一个对象中强类型时才需要这样做。
答案 2 :(得分:0)
你考虑过使用泛型吗?
如果Task,Order和Transmission都继承自Property之类的基类,那么您可以公开获取所需值的常用方法。 GetMyValue()其中T:Property
目前还不是很清楚你想要实现的目标。