Search code examples
c#reflectionpropertyinfo

c# how to get input buffer property value as string


I need to get the value of each property in an inputbuffer, I can get the name of the property but I can't get the value, I need to add the name and the value in a dictionary. This is my code:

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() );
    }
}

I got this exception: Object reference not set to an instance of an object


Solution

  • You just need to call GetValue on the inputColumn object like this:

    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));
            }
        }
    }
    

    You can simplify the whole method with a bit of Linq, and also make it generic like this:

    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));
    }
    

    You could also be even safer by making sure you only call properties that return string values with an additional Where clause:

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

    Or if you want to include other property types (e.g. int), then you will need to revert to using ToString:

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

    That way you can reuse this method for other object types.