c # как получить значение свойства входного буфера в виде строки

Мне нужно получить значение каждого свойства в буфере ввода, я могу получить имя свойства, но не могу получить значение, мне нужно добавить имя и значение в словарь. Это мой код:

public override void Input0_ProcessInputRow(Input0Buffer Row)
{
    Dictionary<string, string> body = new Dictionary<string, string>();

    foreach (PropertyInfo inputColumn in Row.GetType().GetProperties())
    {
        if (!inputColumn.Name.EndsWith("IsNull"))
                body.Add(inputColumn.Name, Row.GetType().GetProperty(inputColumn.Name).GetValue(Row).ToString() );
    }
}

Я получил это исключение: ссылка на объект не установлена ​​​​на экземпляр объекта


person marko    schedule 13.03.2020    source источник
comment
@DavidG в Visual Studio я получаю аргумент 2: не могу преобразовать объект в строку   -  person marko    schedule 13.03.2020
comment
Конечно, потому что GetValue возвращает object. Если вы знаете, что тип на самом деле string, приведите его.   -  person Jeroen Mostert    schedule 13.03.2020
comment
Что ж, .ToString будет делать то же самое (за исключением того, что он не будет генерировать, если это не строка), неясно, откуда вы получаете эту ошибку аргумента.   -  person DavidG    schedule 13.03.2020


Ответы (2)


Вам просто нужно вызвать GetValue для объекта inputColumn следующим образом:

public override void Input0_ProcessInputRow(Input0Buffer Row)
{
    Dictionary<string, string> body = new Dictionary<string, string>();

    foreach (PropertyInfo inputColumn in Row.GetType().GetProperties())
    {
        if (!inputColumn.Name.EndsWith("IsNull"))
        {
            body.Add(inputColumn.Name, 
               (string)inputColumn.GetValue(Row));
        }
    }
}

Вы можете упростить весь метод с помощью Linq, а также сделать его общим:

public void ProcessRow<T>(T item)
{
    var body = typeof(T) // Get the type
        .GetProperties() // Get all properties
        .Where(p => !p.Name.EndsWith("IsNull")) // Exclude properties ending with "IsNull"
        .ToDictionary( // Return a dictionary
            p => p.Name, 
            p => (string) p.GetValue(item));
}

Вы также можете быть еще безопаснее, убедившись, что вы вызываете свойства, которые возвращают строковые значения, только с дополнительным предложением Where:

.Where(p => p.PropertyType == typeof(string))

Или, если вы хотите включить другие типы свойств (например, int), вам нужно будет вернуться к использованию ToString:

p => p.GetValue(item).ToString()

Таким образом, вы можете повторно использовать этот метод для других типов объектов.

person DavidG    schedule 13.03.2020
comment
Теперь я получаю эту ошибку: Не удается преобразовать System. Int32 в System.String - person marko; 13.03.2020
comment
Потому что не все ваши свойства являются строками. Либо используйте дополнительную строку, которую я указал в конце моего ответа, либо вернитесь к использованию ToString вместо приведения. - person DavidG; 13.03.2020
comment
Тогда вы не используете мой код, вам нужно показать нам свой настоящий код, иначе я ничего не смогу сделать. - person DavidG; 13.03.2020
comment
Я отсортировал его, у меня было нулевое значение в одном из свойств, и оно вызывало исключение, теперь это работает, спасибо! - person marko; 13.03.2020

вы должны использовать переменные для каждого вызова метода, например var rowType = Row.GetType();.

Например, Row.GetType().GetProperty(inputColumn.Name) можно заменить на inputColumn.

Вы можете повторно использовать переменные в одном и том же методе, и трассировка стека покажет вам строку, в которой возникает нулевая ссылка. Пожалуйста, проверьте трассировку стека, она покажет вам имя метода, вызвавшего ошибку.

Я предполагаю, что .GetValue(Row) возвращает ноль.

person oleksa    schedule 13.03.2020