【问题标题】:How to using class with static method in C#?如何在 C# 中使用具有静态方法的类?
【发布时间】:2016-02-18 10:24:46
【问题描述】:

我想使用 ToDataTable() 类将 List 转换为 DataTable。 问题是:类ToDataTable() 使用static 方法,它会出错。 我知道这个错误,但我不知道如何解决它。

错误代码为:Extension method must be defined in a non-generic static class

我使用的代码是:

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

以及将 List 转换为 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;
}

我在互联网上进行研究。比如,把我的班级改成静态的。 但我改成静态,错误继续出现: Static class 'MyClass.MainForm' cannot derive from type 'System.Windows.Forms.Form'. Static classes must derive from object..

我的代码是这样的:

public static class MainForm : System.Windows.Forms.Form
{
}

【问题讨论】:

  • 我认为你应该将这个方法 ToDataTable 移动到静态类中,并将其作为扩展方法。所以你可以简单地使用它,dtProxy = proxyInfos.ToDataTable();

标签: c#


【解决方案1】:

只需删除this

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

并用作简单的静态方法

或者将此函数移动到单独的静态类

喜欢

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

【讨论】:

  • 现货,有一点小事:CLR 命名约定认为持有扩展方法的类应该使用后缀“Extensions”命名,在本例中为“ListExtensions”。
  • 我尝试添加到静态类但不起作用。但是当我删除this 时,它运行得很好。谢谢
【解决方案2】:

不,您不能将表单定义为static 类,因为它必须被实例化。要拥有扩展方法,您需要一个静态类,但不一定需要更改表单类。创建一个新的静态类并将您的扩展方法放在那里。请参阅MSDN docs here。

扩展方法被定义为静态方法,但被 使用实例方法语法。

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

另一个建议,将您的IList&lt;T&gt; 更改为IEnumerable&lt;T&gt;,因为您可以为更多集合保留扩展方法,因为IEnumerable 比IList 更抽象。

【讨论】:

  • 感谢您的提示 - IEnumerable
【解决方案3】:

你不能做public static class MainForm : System.Windows.Forms.Form,因为你不能从另一个类派生静态类。

虽然你可以这样做:

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

确保您需要访问扩展的位置包括包含扩展方法的命名空间。所以任何IList&lt;T&gt; 都可以访问这个ToDataTable&lt;T&gt; 方法。

【讨论】:

    【解决方案4】:

    将你的方法移动到静态类中,并按照下面给出的扩展方法,

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

    并替换你的行,

    dtProxy = ToDataTable(proxyInfos);
    

    与,

    dtProxy = proxyInfos.ToDataTable();
    

    【讨论】:

    • 感谢您的回答。我正在尝试您的代码。这是工作。
    猜你喜欢
    • 2012-04-19
    • 2011-01-21
    • 2021-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多