简体   繁体   中英

Generic method accepting List<T>

I have 5 classes which represent a row of a grid of data. All of these classes inherit from an abstract class of CoreGrid.

I have an export mechanism, which uses reflection to figure out the columns to export. At the minute, I have a method for each type of grid (ExportOrganisations, ExportPeople, ExportEvents) however this is horrible, as the only thing different between them is the part where it looks up the type. Example code is shown below:

public string ExportEvents(List<EventGrid> events)
{
    DataTable report = new DataTable();

    EventGrid ev = new EventGrid();

    Type t = ev.GetType();

    PropertyInfo[] props = t.GetProperties();

    foreach (PropertyInfo prop in props)
    {
        if (!prop.Name.Contains("ID"))
        {
            report.Columns.Add(prop.Name);
        }
    }

    foreach (var item in events)
    {
        DataRow dr = report.NewRow();

        Type itemType = item.GetType();

        PropertyInfo[] itemProps = itemType.GetProperties();

        foreach (PropertyInfo prop in itemProps)
        {
            if (report.Columns.Contains(prop.Name))
            {
                if (prop.GetValue(item, null) != null)
                {
                    dr[prop.Name] = prop.GetValue(item, null).ToString().Replace(",", string.Empty);
                }
            }
        }

        report.Rows.Add(dr);
    }

    return GenerateCSVExport(report, ExportType.Events);
}

My question is, how would I condense these methods into one method where the method accepts a list which inherits from CoreGrid?

public string ExportEvents<T>(List<T> events) where T : CoreGrid
{
    DataTable report = new DataTable();

    Type t = typeof(T);

    //your magic here
}

And then use

var result = ExportEvents<EventGrid>(eventList);

Should be something like this. Due to the ability to infer types, you do not have to change current call signatures, just point everything to the generic method:

//if myList is a list of CoreGrid or derived.
string export = ExportEvents(myList);


public string ExportEvents<T>(List<T> events) where T : CoreGrid
{
    DataTable report = new DataTable();

    Type t = typeof(T);

    PropertyInfo[] props = t.GetProperties();

    foreach (PropertyInfo prop in props)
    {
        if (!prop.Name.Contains("ID"))
        {
            report.Columns.Add(prop.Name);
        }
    }

    foreach (var item in events)
    {
        DataRow dr = report.NewRow();

        Type itemType = item.GetType();

        PropertyInfo[] itemProps = itemType.GetProperties();

        foreach (PropertyInfo prop in itemProps)
        {
            if (report.Columns.Contains(prop.Name))
            {
        var propValue = prop.GetValue(item, null)
                if (propValue != null)
                {
                    dr[prop.Name] = propValue.ToString().Replace(",", string.Empty);
                }
            }
        }

        report.Rows.Add(dr);
    }

    return GenerateCSVExport(report, ExportType.Events);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM