Как я могу сохранить ссылку на свойство объекта в другом объекте? - PullRequest
6 голосов
/ 18 августа 2010

Это приложение C # winforms.

Введение

Я создаю форму, которая позволит пользователям импортировать данные из существующей базы данных MySql или SQL Server в мою базу данных SQL Server. Это позволяет пользователям быстро импортировать IP-адреса и другие данные без необходимости повторного ввода их через элемент управления.

Пример:

Упрощенно, у меня есть два объекта, FieldObject и SensorObject. 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 оно принадлежит. 1027 *

Например:

// 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 # подходит для такого рода приложений. Я посмотрел на справочные значения и рефлексию, и ни один из них не кажется подходящим.

Я ценю любые идеи и советы или даже способы переосмыслить этот подход.

Ответы [ 3 ]

2 голосов
/ 18 августа 2010

Вы должны использовать отражение, чтобы сделать это. Должен закончиться как что-то вроде:

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 получает информацию о свойствах для каждого свойства, которую можно использовать для установки значения.

Конечно, информация о свойствах может быть кэширована. Просто напишите это один раз и рефакторинг, как только он запустится. Не слишком усложняйте это, это называется преждевременной оптимизацией и ведет прямо к черту;)

1 голос
/ 18 августа 2010

Вы можете сделать это с отражением.Вы получаете PropertyInfo объекта proprty с указанным именем, получаете MethodInfo установщика и затем вызываете его.

Однако может быть возможно сохранить ассоциативный массив (Dictionary или HastTable и т. Д.)значений, хранящихся по имени, с которыми было бы намного легче справиться, если это необходимо.

1 голос
/ 18 августа 2010

На самом деле отражение - неплохая идея, особенно если вы заполняете словарь PropertyInfo экземплярами для каждого имени свойства.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...