2

I am getting the exception mentioned in the title at the line of code

values[i] = Props[i].GetValue(item, null); 

and I am not sure what is causing this. Any help would be appreciated.

public static DataTable ToDataTable<T>(List<T> items)
{
    DataTable dataTable = new DataTable(typeof(T).Name);


    PropertyInfo[] Props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
    foreach (PropertyInfo prop in Props)
    {

        var type = (prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>) ? Nullable.GetUnderlyingType(prop.PropertyType) : prop.PropertyType);

        dataTable.Columns.Add(prop.Name, type);
    }
    foreach (T item in items)
    {
        var values = new object[Props.Length];
        for (int i = 0; i < Props.Length; i++)
        {
            values[i] = Props[i].GetValue(item, null);
        }
        dataTable.Rows.Add(values);
    }

    return dataTable;
}
David Tansey
  • 5,813
  • 4
  • 35
  • 51
  • What type of data are you passing in? The method seems to work correctly with my tests. For example, here it is with a basic collection: https://dotnetfiddle.net/6RWBpz – Mun Oct 20 '17 at 18:58
  • Found you a related article with a quick google of your subject line: https://stackoverflow.com/questions/32143085/parameter-count-mismatch-when-getting-value-of-property-using-reflection – J. Schmale Oct 20 '17 at 19:02
  • The data is a list of strings. –  Oct 20 '17 at 19:03
  • The dynamic type whatever it is can only be 1 value which is equal to T. I think your looping and setting of dataTable columns to multiple types from Props is incorrect. But it's a guess. – boateng Oct 20 '17 at 19:12

2 Answers2

2

If this line is throwing the exception

values[i] = Props[i].GetValue(item, null); 

...then it means you have a property that requires a parameter. In c#, the only type of property that takes a parameter is an indexer. My guess is you should just exclude the indexer from the loop.

See this question which tells you how to detect an indexer.

You can probably fix this by changing one line. Change this...

PropertyInfo[] Props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);

...to this....

PropertyInfo[] Props = typeof(T)
    .GetProperties(BindingFlags.Public | BindingFlags.Instance)
    .Where(p => p.GetIndexParameters == null))
    .ToArray();
John Wu
  • 50,556
  • 8
  • 44
  • 80
0

The issue was actually in the data that I passed into the method(a list of strings). It appeared that the GetValue() method was looking for an object. I created a class with a string property and changed my list type that was being passed in to the class and set the property in the class to the string that I was passing to the list in my foreach loop. Sorry if this doesn't make sense just trying to explain how I solved this, but the problem probably could have been solved a number of ways. Thanks, all.