1

I want using class ToDataTable() to convert List to DataTable. Problem is: class ToDataTable() using static method and it make error. I know this error but I don't know how to resolve it.

The error code is: Extension method must be defined in a non-generic static class

My code using is:

var proxyInfos = proxyL
            .Where(l => l.Contains(" US "))
            .Select(l => l.Split(' '))
            .Select(tokens => new
            {
                IP = tokens[0],
                Port = tokens[1]
            })
            .ToList();
        dtProxy = ToDataTable(proxyInfos);

And class to convert List to DataTable:

public static DataTable ToDataTable<T>(this IList<T> data)
{
    PropertyDescriptorCollection properties =
        TypeDescriptor.GetProperties(typeof(T));
    DataTable table = new DataTable();
    foreach (PropertyDescriptor prop in properties)
        table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);
    foreach (T item in data)
    {
        DataRow row = table.NewRow();
        foreach (PropertyDescriptor prop in properties)
            row[prop.Name] = prop.GetValue(item) ?? DBNull.Value;
        table.Rows.Add(row);
    }
    return table;
}

I was research on the internet. Like, change my class to static. But I change to static and error continues to appear: Static class 'MyClass.MainForm' cannot derive from type 'System.Windows.Forms.Form'. Static classes must derive from object..

My code like this:

public static class MainForm : System.Windows.Forms.Form
{
}
lan
  • 53
  • 1
  • 1
  • 4
  • Possible duplicate of [Static classes must derive from object (C#)](http://stackoverflow.com/questions/6496707/static-classes-must-derive-from-object-c) – Alfie Goodacre Feb 18 '16 at 10:29
  • I think you should move this method, ToDataTable into static class and make it as Extension method. So you can simply use it as, dtProxy = proxyInfos.ToDataTable(); – Hiren Visavadiya Feb 18 '16 at 10:29

4 Answers4

3

Just remove this

public static DataTable ToDataTable<T>(IList<T> data)

and use as simple static method

Or move this function to separated static class

like

public static class UnilityExtensions
{
    public static DataTable ToDataTable<T>(this IList<T> data)
    { ... }
}
Grundy
  • 13,356
  • 3
  • 35
  • 55
  • 2
    Spot-on, with a minor minor thing: CLR naming conventions hold that classes holding extension methods should be named with the suffix "Extensions", in this case "ListExtensions". – Dai Feb 18 '16 at 10:29
  • I tried add to static class but not work. But when I remove `this`, that run perfectly. Thanks – lan Feb 18 '16 at 10:37
2

No, you cannot define a form as a static class because it have to be instanced. TO have an extension method you need a static class, but not necessarily you need to chnage your form class. Create a new static class and put your extensions methods there. See the MSDN docs here.

Extension methods are defined as static methods but are called by using instance method syntax.

public static class MyExtensions
{
    public static DataTable ToDataTable<T>(this IEnumerable<T> str)
    {
        PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(typeof(T));
        DataTable table = new DataTable();

        foreach (PropertyDescriptor prop in properties)
            table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);

        foreach (T item in data)
        {
            DataRow row = table.NewRow();
            foreach (PropertyDescriptor prop in properties)
                row[prop.Name] = prop.GetValue(item) ?? DBNull.Value;
            table.Rows.Add(row);
        }

        return table;
    }
}   

Another suggestion, change you IList<T> to IEnumerable<T> because you can keep an extension method for more collections because the IEnumerable is more abstract than IList.

Felipe Oriani
  • 37,948
  • 19
  • 131
  • 194
2

You cant do public static class MainForm : System.Windows.Forms.Form because you cant derive static class from another class.

Although you can do this:

using SomeNamespace
{
    public static class FormExtension
    {
        public static DataTable ToDataTable<T>(this IList<T> data)
        {
           ...
        }
    }
}

Make sure the place where you need to access the extension includes the namespace containing the Extension method. So any IList<T> will have access to this ToDataTable<T> method.

Carbine
  • 7,849
  • 4
  • 30
  • 54
0

Move your method into static class, and make it extension method as per below given,

 public static class Extension
{
    public static DataTable ToDataTable<T>(this IList<T> data)
    {
        PropertyDescriptorCollection properties =
            TypeDescriptor.GetProperties(typeof(T));
        DataTable table = new DataTable();
        foreach (PropertyDescriptor prop in properties)
            table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);
        foreach (T item in data)
        {
            DataRow row = table.NewRow();
            foreach (PropertyDescriptor prop in properties)
                row[prop.Name] = prop.GetValue(item) ?? DBNull.Value;
            table.Rows.Add(row);
        }
        return table;
    }
}

and replace your line,

dtProxy = ToDataTable(proxyInfos);

with,

dtProxy = proxyInfos.ToDataTable();
Hiren Visavadiya
  • 485
  • 1
  • 3
  • 15