276

I'm getting the error:

Extension methods must be defined in a non-generic static class

On the line:

public class LinqHelper

Here is the helper class, based on Mark Gavells code. I'm really confused as to what this error means as I am sure it was working fine when I left it on Friday!

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;
    }
}
abatishchev
  • 98,240
  • 88
  • 296
  • 433
Tom Gullen
  • 61,249
  • 84
  • 283
  • 456

11 Answers11

371

change

public class LinqHelper

to

public static class LinqHelper

Following points need to be considered when creating an extension method:

  1. The class which defines an extension method must be non-generic, static and non-nested
  2. Every extension method must be a static method
  3. The first parameter of the extension method should use the this keyword.
crypted
  • 10,118
  • 3
  • 39
  • 52
  • If you have placed the class in App_Code then it is bound to have the static keyword in the class definition, but if you place it in any other folder then its fine to use it as normal class. – D.T. Sep 09 '14 at 06:58
  • 1
    In one case, I had used `public static class IQueryable where T : MyBaseClass` which also generates this error. The `where T : MyBaseClass` phrase belongs on the individual methods without `` on the static class. – Bron Davies Feb 11 '16 at 19:09
  • 1
    But what if the class is Partial? This solution did not work for me. – Fandango68 Apr 24 '18 at 05:47
  • 1
    Thanks buddy, I got caught on the "this" parameter! – Roberto Gata Apr 29 '19 at 11:40
  • 1
    Beware that you may get this compiler if you inadvertently converted your class to an extension method (according to the compiler). See [this answer](https://stackoverflow.com/a/21921828/589259) with regards to static methods and [this answer](https://stackoverflow.com/a/52216538/589259) with regards to `this` method arguments. – Maarten Bodewes May 16 '19 at 15:18
  • If you didn't intend to have static methods, see [this answer](https://stackoverflow.com/a/52216538/3437608) below as well! – Cullub Aug 12 '19 at 15:04
93

if you do not intend to have static functions just get rid of the "this" keyword in the arguments.

Rohan Bhosale
  • 1,050
  • 7
  • 5
  • 25
    I was scratching my head for awhile trying to figure out why Visual Studio thought I was trying to make one of my classes an extension method. Turns out I had a `this` keyword buried in on of my method signatures. Removing it cleared the error. – Fütemire May 01 '19 at 21:17
  • 3
    This was the cause for me. The top answers don't explain why is it caused. – Andrew Sep 15 '20 at 06:48
  • 3
    @Fütemire - I had same issue. I am suspicious that some auto-complete VS BS put it in there. – Ian Jul 18 '21 at 17:48
24

Add keyword static to class declaration:

// this is a non-generic static class
public static class LinqHelper
{
}
abatishchev
  • 98,240
  • 88
  • 296
  • 433
20

A work-around for people who are experiencing a bug like Nathan:

The on-the-fly compiler seems to have a problem with this Extension Method error... adding static didn't help me either.

I'd like to know what causes the bug?

But the work-around is to write a new Extension class (not nested) even in same file and re-build.

Figured that this thread is getting enough views that it's worth passing on (the limited) solution I found. Most people probably tried adding 'static' before google-ing for a solution! and I didn't see this work-around fix anywhere else.

Stephan Luis
  • 911
  • 1
  • 9
  • 24
  • 1
    I had the same issue. I just realized that I added a static function within the class and forgot to comment it out. So that made my class static, and hence was giving this error. Check if there are any static objects in your class. – Mahesh Aug 19 '16 at 21:39
20

Try changing

public class LinqHelper

to

 public static class LinqHelper
Drew
  • 24,851
  • 10
  • 43
  • 78
Nathan
  • 6,095
  • 2
  • 35
  • 61
17

I was scratching my head with this compiler error. My class was not an extension method, was working perfectly since months and needed to stay non-static. I had included a new method inside the class:

private static string TrimNL(this string Value)
{...}

I had copied the method from a sample and didn't notice the "this" modifier in the method signature, which is used in extension methods. Removing it solved the issue.

davidthegrey
  • 1,205
  • 2
  • 14
  • 23
16

Change it to

public static class LinqHelper
Rik
  • 28,507
  • 14
  • 48
  • 67
6

I ran into this when converting a project to use dependency injection. If a method declaration contains the “this” keyword, VS will give the warning. In my case, I was able to remove “this” from all of the method declarations. If using “this” is required, you will have to make it static.

 public static IOrderedQueryable<T> OrderBy<T>(this IQueryable<T> source, string property)

changed to

     public static IOrderedQueryable<T> OrderBy<T>(IQueryable<T> source, string property)

You might need to code around not using the “this” keyword for the method declaration if you want to avoid using a static class with static methods. If “this” is only required for some methods, those methods can be moved to a separate public static class.

Brandon Dekker
  • 271
  • 3
  • 8
1

Extension method should be inside a static class. So please add your extension method inside a static class.

so for example it should be like this

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

    }
Debendra Dash
  • 5,334
  • 46
  • 38
1

Try changing it to static class and back. That might resolve visual studio complaining when it's a false positive.

visc
  • 4,794
  • 6
  • 32
  • 58
0

I encountered a similar issue, I created a 'foo' folder and created a "class" inside foo, then I get the aforementioned error. One fix is to add "static" as earlier mentioned to the class which will be "public static class LinqHelper".

My assumption is that when you create a class inside the foo folder it regards it as an extension class, hence the following inter alia rule apply to it:

1) Every extension method must be a static method

WORKAROUND If you don't want static. My workaround was to create a class directly under the namespace and then drag it to the "foo" folder.