Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在另一个对象中存储对对象属性的引用?_C#_Winforms_Object_Properties - Fatal编程技术网

C# 如何在另一个对象中存储对对象属性的引用?

C# 如何在另一个对象中存储对对象属性的引用?,c#,winforms,object,properties,C#,Winforms,Object,Properties,这是一个C#winforms应用程序 前言: 我正在创建一个表单,允许用户将现有MySql或SQL Server数据库中的数据导入我的SQL Server数据库。这允许用户快速导入IP地址和其他数据,而无需通过控件重新输入 示例: 简化后,我有两个对象,FieldObject和SensorObject字段对象用于存储源和目标数据库字段名称和类型SensorObject是我稍后从数据库中的记录填充的对象。为了简单起见,我省略了与问题无关的类型处理和其他功能。(DestinationField的数据

这是一个C#winforms应用程序

前言:

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

示例:

简化后,我有两个对象,
FieldObject
SensorObject
<代码>字段对象用于存储源和目标数据库字段名称和类型
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]);
}
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]);
}
我不确定C#中的哪种技术适合这种应用。我已经研究了参考值和反射,两者似乎都不合适


我很欣赏任何见解和建议,甚至是重新思考这种方法的方法。

事实上,反射并不是一个坏主意,特别是如果你在字典中为每个属性名填充
属性信息
实例。

你必须使用反射来实现这一点。 结果应该是:

foreach(FieldObject f in myFieldList)
{
    mySensor(f.mySensorField) = Convert.ToString(Reader[f.DestinationField]);
}
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获取可用于设置值的每个属性的属性信息


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

你可以通过反射来实现。您将获得具有所讨论名称的property的PropertyInfo,获取setter的MethodInfo,然后调用它


不过,也可以存储按名称存储的值的关联数组(字典或HastTable等),如果合适的话,这将更容易处理。

您可以使用ORM解决此问题,这样就不必编写此冗余代码了吗?对象关系映射?我怀疑,如果我不必查找“ORM”是什么,我可能会使用它对不起,大多数时候还是新手!看看NHibernate:从长远来看,ORM消除了使用关系数据库的大部分痛苦,但是它们需要一些工作才能开始。因此,
ORM::RDBM痛苦
as
酒精::抑制
?:)JY:根据经验,在决定重新发明轮子之前,最好先试用一下。:-)这看起来非常有帮助,它有助于有人谁了解反射和它的使用指向正确的方向!如果将循环内容替换为
lookup.Add(field.Name,field)
,其中
lookup
是一个
Dictionary
,这就是以后缓存这些结果所需的全部内容。我不清楚
阅读器[myField.DestinationField]
是什么,但我不确定是否需要将其转换为字符串。或者,如果您这样做了,我会认为您应该调用
x.ToString()
而不是使用
Convert.ToString(x)
。实际上,我有一个完整的库来读取SQL中的内容,但我不想使用专有方法名来分散对问题的注意力,所以我只使用了一个占位符。我想使用
Reader.GetString(“fieldname”)
但是MS-SQL需要一个整数(一个从零开始的列序号)来指定列,而不是字段名。为了明确字段名关联,我使用了
convert
hack.:)@泽比:我在让代码的LINQ部分正常工作方面遇到了一些问题,我最近开始使用LINQ处理列表(这是一个非常好的工具!),但我不确定如何“修复”
。首先是
查询。我想也许我需要试试:
var info=sensorFields.Where(x=>x==field.Name).First()。我相信我最终能得到它,但我想我会给你一些提示。在
属性信息上调用
GetSetMethod
可能是有意义的,它会向setter本身返回一个“MethodInfo”。@Steven,你说得对。当我开始回答问题时,我忘记了object是什么时候更新的:)修复了,谢谢。只需使用PropertyInfo.SetValue(object,object,object[])@Zebi:如果我们要缓存一些东西,为什么不使用setter的
MethodInfo
而不是
PropertyInfo
。我希望后者只使用前者,这样我们就可以在这方面少走一步。我不认为这一变化会产生明显的影响,但我认为它增加了不必要的复杂性。这就是我建议不用缓存就用简单的方法解决它的原因。如果您看到缓存带来的巨大好处,请实现它。