简体   繁体   中英

How to using class with static method in C#?

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. 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
{
}

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)
    { ... }
}

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 .

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.

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

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