How can I store a reference to object property in another object?
This is a C# winforms app.
Preface:
I am creating a form that will allow users to import data from an existing MySql or SQL Server database into my SQL Server database. This allows users to quickly import IP addresses and other data without having to re-enter it via a control.
Example:
Simplified, I have two objects, FieldObject
and SensorObject
. FieldObject
exists to store the source and destination database field names and types. SensorObject
is the object I later populate from the records in the database. For simplicity's sake, I am omitting the type handling and other functionality that is not relevant to the question. (The data for DestinationField
is limited to a list that I provide the user, and comes from an array or list within the program.) Here is an example of both:
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;}
}
Problem:
When the user populates the various fields of FieldObject
, I use the information to populate the destination database, though I have a large switch statement that checks the destination field name to know what property of SensorObject
it belongs.
For example:
// 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;
}
As you can see it would require more redundant code to handle more properties for the object.
Question:
I'd like some way of storing the property of SensorObject
that the data belongs to, so that when iterating FieldObjects
in a list, I can effectively eliminate the switch statement.
Something like:
foreach(FieldObject f in myFieldList)
{
mySensor(f.mySensorField) = Convert.ToString(Reader[f.DestinationField]);
}
I am not certain what technique in C# lends itself to this sort of application. I've looked into reference values and reflecti开发者_StackOverflow社区on, and neither seem appropriate.
I appreciate any insight and advice or even ways to rethink this approach.
You have to use reflection to do this. Should end up as something like:
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 gets a property info for each property which can be used to set the value.
Of course property infos can be cached. Just write it once and refactor as soon as it runs. Don't over complicate too much this is called premature optimization and leads straight to hell ;)
Actually, reflection is not a bad idea, particularly if you populate a dictionary with PropertyInfo
instances for each property name.
You can do it with reflection. You get the PropertyInfo of the proprty with the name in question, get the MethodInfo of the setter, and then invoke it.
It might though, be possible to store an associative array (Dictionary or HastTable, etc.) of values stored by name, which would be much easier to deal with if appropriate.
精彩评论