Erweiterungsmethoden müssen in einer nicht generischen statischen Klasse definiert werden


213

Ich erhalte den Fehler:

Erweiterungsmethoden müssen in einer nicht generischen statischen Klasse definiert werden

An der Leitung:

public class LinqHelper

Hier ist die Hilfsklasse, die auf Mark Gavells Code basiert. Ich bin wirklich verwirrt darüber, was dieser Fehler bedeutet, da ich sicher bin, dass er gut funktioniert hat, als ich ihn am Freitag verlassen habe!

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

Antworten:


309

Veränderung

public class LinqHelper

zu

public static class LinqHelper

Folgende Punkte müssen beim Erstellen einer Erweiterungsmethode berücksichtigt werden:

  1. Die Klasse , die eine Verlängerung Methode definiert sein muss non-generic, staticundnon-nested
  2. Jede Erweiterungsmethode muss eine staticMethode sein
  3. Der erste Parameter der Erweiterungsmethode sollte das thisSchlüsselwort verwenden.

Wenn Sie die Klasse in App_Code platziert haben, muss das Schlüsselwort static in der Klassendefinition enthalten sein. Wenn Sie sie jedoch in einem anderen Ordner ablegen, ist es in Ordnung, sie als normale Klasse zu verwenden.
DT

1
In einem Fall hatte ich verwendet, public static class IQueryable<T> where T : MyBaseClasswas auch diesen Fehler erzeugt. Die where T : MyBaseClassPhrase gehört zu den einzelnen Methoden ohne <T>zur statischen Klasse.
Bron Davies

1
Aber was ist, wenn die Klasse Teilweise ist? Diese Lösung hat bei mir nicht funktioniert.
Fandango68

1
Danke Kumpel, ich habe den "this" -Parameter erwischt!
Roberto Gata

1
Beachten Sie, dass Sie diesen Compiler möglicherweise erhalten, wenn Sie Ihre Klasse versehentlich in eine Erweiterungsmethode konvertiert haben (je nach Compiler). Siehe diese Antwort in Bezug auf statische Methoden und diese Antwort in Bezug auf thisMethodenargumente.
Maarten Bodewes

25

Wenn Sie keine statischen Funktionen haben möchten, entfernen Sie einfach das Schlüsselwort "this" in den Argumenten.


6
Ich kratzte mir eine Weile am Kopf, um herauszufinden, warum Visual Studio dachte, ich würde versuchen, eine meiner Klassen zu einer Erweiterungsmethode zu machen. Es stellte sich heraus, dass ich ein thisSchlüsselwort in einer meiner Methodensignaturen vergraben hatte. Durch Entfernen wurde der Fehler behoben.
Fütemire

20

Schlüsselwort staticzur Klassendeklaration hinzufügen:

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

16

Versuchen Sie es zu ändern

public class LinqHelper

zu

 public static class LinqHelper

15

Ändern Sie es in

public static class LinqHelper

15

Ein Workaround für Leute, die einen Fehler wie Nathan haben:

Der On-the-Fly-Compiler scheint ein Problem mit diesem Fehler der Erweiterungsmethode zu haben ... das Hinzufügen statichat mir auch nicht geholfen.

Ich würde gerne wissen, was den Fehler verursacht.

Aber die Work-around ist eine neue Erweiterung Klasse zu schreiben (nicht verschachtelt) sogar in derselben Datei und neu zu bauen.

Es wurde festgestellt, dass dieser Thread genügend Ansichten erhält, sodass es sich lohnt, die (begrenzte) Lösung weiterzugeben, die ich gefunden habe. Die meisten Leute haben wahrscheinlich versucht, "statisch" hinzuzufügen, bevor sie nach einer Lösung gesucht haben! und ich habe diese Problemumgehung nirgendwo anders gesehen.


Ich hatte das gleiche Problem. Ich habe gerade festgestellt, dass ich eine statische Funktion innerhalb der Klasse hinzugefügt und vergessen habe, sie zu kommentieren. Das machte meine Klasse statisch und gab daher diesen Fehler. Überprüfen Sie, ob Ihre Klasse statische Objekte enthält.
Mahesh

1

Die Erweiterungsmethode sollte sich in einer statischen Klasse befinden. Fügen Sie daher Ihre Erweiterungsmethode in eine statische Klasse ein.

so sollte es zum Beispiel so sein

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

    }

Wie unterscheidet sich das von den Antworten vor Jahren?
Maarten Bodewes

1

Versuchen Sie, es in eine statische Klasse und zurück zu ändern. Das könnte dazu führen, dass sich Visual Studio beschwert, wenn es falsch positiv ist.


0

Ich bin auf ein ähnliches Problem gestoßen. Ich habe einen 'foo'-Ordner erstellt und eine "Klasse" in foo erstellt. Dann erhalte ich den oben genannten Fehler. Eine Lösung besteht darin, der Klasse "statisch" hinzuzufügen, wie dies zuvor erwähnt wurde. Dies ist die "öffentliche statische Klasse LinqHelper".

Ich gehe davon aus, dass beim Erstellen einer Klasse im Ordner foo diese als Erweiterungsklasse betrachtet wird. Daher gilt für sie unter anderem die folgende Regel:

1) Jede Erweiterungsmethode muss eine statische Methode sein

Umgehung Wenn Sie keine statische Aufladung wünschen. Meine Problemumgehung bestand darin, eine Klasse direkt unter dem Namespace zu erstellen und sie dann in den Ordner "foo" zu ziehen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.