2010-08-17 101 views
6

这是一个C#winforms应用程序。如何在另一个对象中存储对象属性的引用?

前言:

我创建一个表单,允许用户从现有的MySQL或SQL Server数据库中的数据导入到我的SQL Server数据库。这使用户可以快速导入IP地址和其他数据,而无需通过控件重新输入IP地址和其他数据。

实施例:

简体,我有两个目的,FieldObjectSensorObject。存在FieldObject以存储源和目标数据库字段名称和类型。 SensorObject是我稍后从数据库中的记录填充的对象。为了简单起见,我省略了与问题无关的类型处理和其他功能。 (对于DestinationField的数据仅限于我提供用户的列表,以及来自节目内的数组或列表。)在这里是两个的一个示例:

public class FieldObject 
{ 
    public string DestinationField {get; set;} 
    public string SourceField {get; set;} 
} 

public class SensorObject 
{ 
    public string Name {get; set;} 
    public string IPAddress {get; set;} 
} 

问题:

当用户填充FieldObject的各个字段时,我使用这些信息来填充目标数据库,尽管我有一个大的switch语句来检查目标字段名称,以知道它属于哪个属性SensorObject

例如:

// Reader is a SqlDataReader with the prerequisite database connection 
FieldObject myField = new FieldObject 
    { 
     DestinationField = "name", 
     SourceField = "proprietary" 
    }; 
SensorObject mySensor = new SensorObject(); 
switch (myField.DestinationField) 
{ 
    case "name": 
     mySensor.Name = Convert.ToString(Reader[myField.DestinationField]); 
     break; 
    case "ip_address": 
     mySensor.IPAddress = Convert.ToString(Reader[myField.DestinationField]); 
     break; 
} 

正如你可以看到它需要更多的冗余代码来处理的对象更多的属性。

问:

我想存储的SensorObject属性的某种方式,数据属于,以便在列表迭代FieldObjects的时候,我可以有效地消除switch语句。

喜欢的东西:

foreach(FieldObject f in myFieldList) 
{ 
    mySensor(f.mySensorField) = Convert.ToString(Reader[f.DestinationField]); 
} 

我不能肯定什么技术在C#本身借给这种应用。我已经研究过参考价值和反思,而且都不合适。

我很感谢任何见解和建议,甚至重新考虑这种方法。

+0

你可以使用ORM来解决这个问题,所以你不必编写这个冗余代码? – 2010-08-17 20:36:18

+0

对象关系映射?我怀疑如果我不需要查看“ORM”是什么,我可能可以使用它。 :)对不起,这里仍然是新手! – JYelton 2010-08-17 20:40:42

+0

看看NHibernate:http://nhforge.org/wikis/howtonh/your-first-nhibernate-based-application.aspx从长远来看,ORM消除了使用关系数据库的大部分痛苦,然而它们需要一些工作开始。 – Zebi 2010-08-17 20:46:32

回答

2

你必须使用反射来做到这一点。 应该结束了,就像这样:

var sensorFields = typeof(SensorObject).GetProperties() 
foreach(var field in fields) 
{ 
    var info = sensorFields.First(sensorField => sensorField.Name == field.Name); 
    var value = Convert.ToString(Reader[field.Destination]); 
    info.SetValue(sensorObj, value, new object[0]); 
} 

的GetProperties,用于获取可用于设置值的每个属性的属性信息。

当然,可以缓存属性信息。只需写一次,一旦运行就重构。不要太复杂太多,这被称为过早优化,并导致直接地狱;)

+0

这看起来非常有帮助,它有助于让有人了解反射及其用途以指出正确的方向! – JYelton 2010-08-17 20:38:07

+0

如果用'lookup.Add(field.Name,field)'替换循环内容,其中'lookup'是一个'Dictionary ',这就是您稍后需要缓存这些结果的全部内容。 – 2010-08-17 20:40:53

+0

我不清楚'Reader [myField.DestinationField]是什么,但我不确定你需要将它转换为字符串。或者,如果你这样做了,我会认为你只需调用'x.ToString()'而不是使用'Convert.ToString(x)'。 – 2010-08-17 20:43:22

1

实际上,反射并不是一个坏主意,特别是如果您为每个属性名称填入PropertyInfo实例的字典。

1

你可以用反射做到这一点。你得到问题名称的属性的PropertyInfo,获取setter的MethodInfo,然后调用它。

虽然可以存储通过名称存储的值的关联数组(Dictionary或HastTable等),如果适当,这将更容易处理。

+1

在PropertyInfo中调用'GetSetMethod'可能有意义,它会向设置者本身返回一个'MethodInfo'。 – 2010-08-17 20:45:44

+0

@Steven,对吧。当我开始回答问题时,我忘记了什么时候更新了对象:)修正了,谢谢。 – 2010-08-17 20:51:59

+1

只需使用PropertyInfo.SetValue(Object,Object,Object []) – Zebi 2010-08-17 21:03:19

相关问题