2011-05-23 69 views
143

我得到的錯誤定義擴展方法必須在非泛型靜態類

public class LinqHelper 

這裏是輔助類的基礎上,馬克Gavells碼。我真的很困惑這個錯誤是什麼意思,因爲我確信當我在星期五離開時它工作的很好!

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using System.Linq.Expressions; 
using System.Reflection; 

/// <summary> 
/// Helper methods for link 
/// </summary> 
public class LinqHelper 
{ 
    public static IOrderedQueryable<T> OrderBy<T>(this IQueryable<T> source, string property) 
    { 
     return ApplyOrder<T>(source, property, "OrderBy"); 
    } 
    public static IOrderedQueryable<T> OrderByDescending<T>(this IQueryable<T> source, string property) 
    { 
     return ApplyOrder<T>(source, property, "OrderByDescending"); 
    } 
    public static IOrderedQueryable<T> ThenBy<T>(this IOrderedQueryable<T> source, string property) 
    { 
     return ApplyOrder<T>(source, property, "ThenBy"); 
    } 
    public static IOrderedQueryable<T> ThenByDescending<T>(this IOrderedQueryable<T> source, string property) 
    { 
     return ApplyOrder<T>(source, property, "ThenByDescending"); 
    } 
    static IOrderedQueryable<T> ApplyOrder<T>(IQueryable<T> source, string property, string methodName) 
    { 
     string[] props = property.Split('.'); 
     Type type = typeof(T); 
     ParameterExpression arg = Expression.Parameter(type, "x"); 
     Expression expr = arg; 
     foreach (string prop in props) 
     { 
      // use reflection (not ComponentModel) to mirror LINQ 
      PropertyInfo pi = type.GetProperty(prop); 
      expr = Expression.Property(expr, pi); 
      type = pi.PropertyType; 
     } 
     Type delegateType = typeof(Func<,>).MakeGenericType(typeof(T), type); 
     LambdaExpression lambda = Expression.Lambda(delegateType, expr, arg); 

     object result = typeof(Queryable).GetMethods().Single(
       method => method.Name == methodName 
         && method.IsGenericMethodDefinition 
         && method.GetGenericArguments().Length == 2 
         && method.GetParameters().Length == 2) 
       .MakeGenericMethod(typeof(T), type) 
       .Invoke(null, new object[] { source, lambda }); 
     return (IOrderedQueryable<T>)result; 
    } 
} 

回答

226

變化

public class LinqHelper 

public static class LinqHelper 

以下幾點需要創建擴展方法時要考慮:

  1. 定義的類的擴展方法必須是non-genericstaticnon-nested
  2. 每個擴展方法必須是static方法
  3. 擴展方法應使用this關鍵字的第一個參數。
+1

另外添加*非嵌套*在第一點。 – nawfal 2013-06-02 07:16:51

+0

如果您已將該類放入App_Code中,那麼它肯定會在類定義中使用static關鍵字,但如果將其放在任何其他文件夾中,則可以將其用作普通類。 – 2014-09-09 06:58:16

+0

在一個案例中,我曾使用'public static class IQueryable where T:MyBaseClass' which which also generate this error。 'where T:MyBaseClass'短語屬於靜態類上沒有''的單個方法。 – 2016-02-11 19:09:14

21

添加關鍵字static和類聲明:

// this is a non-generic static class 
public static class LinqHelper 
{ 
} 
16

將其更改爲

public static class LinqHelper 
14

嘗試改變

public class LinqHelper 

public static class LinqHelper 
5

一個變通的誰遇到像內森的錯誤的人:在即時編譯器似乎也與此擴展方法誤差的問題...添加

static沒有幫助我也是。

我想知道是什麼原因造成的錯誤?

但是解決方法即使在相同的文件中也要編寫新的擴展類(不嵌套)並重新構建。

認爲此線程獲得了足夠的視圖,值得傳遞(有限)的解決方案,我發現。大多數人可能會嘗試在谷歌解決方案之前添加'靜態'!我沒有在其他地方看到這個解決方法。

+0

我有同樣的問題。我只是意識到我在課堂上添加了一個靜態函數,並忘記將其註釋掉。所以這讓我的類變成了靜態的,因此出現了這個錯誤。檢查班級中是否有任何靜態對象。 – Mahesh 2016-08-19 21:39:48

0

擴展方法應該在靜態類中。 因此,請將您的擴展方法添加到靜態類中。

因此,例如,它應該是這樣的

public static class myclass 
    { 
     public static Byte[] ToByteArray(this Stream stream) 
     { 
      Int32 length = stream.Length > Int32.MaxValue ? Int32.MaxValue : Convert.ToInt32(stream.Length); 
      Byte[] buffer = new Byte[length]; 
      stream.Read(buffer, 0, length); 
      return buffer; 
     } 

    } 
-1

嘗試將其更改爲靜態類和背部。這可能會解決視覺工作室在誤報時抱怨。

-1

當你在星期五離開它時它工作的很好,但是發生了什麼?因爲某人(或者你自己)加了this

如果您不想將該類轉換爲static,則可以從方法聲明中刪除this

例如:

public static IOrderedQueryable<T> OrderBy<T>([delete ->]this[<- /delete] IQueryable<T> source, string property) 
    { 
     return ApplyOrder<T>(source, property, "OrderBy"); 
    } 
相關問題