I metodi di estensione devono essere definiti in una classe statica non generica


214

Ricevo l'errore:

I metodi di estensione devono essere definiti in una classe statica non generica

Sulla linea:

public class LinqHelper

Ecco la classe helper, basata sul codice di Mark Gavells. Sono davvero confuso su cosa significhi questo errore in quanto sono sicuro che funzionava bene quando l'ho lasciato venerdì!

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

Risposte:


309

modificare

public class LinqHelper

per

public static class LinqHelper

I seguenti punti devono essere considerati durante la creazione di un metodo di estensione:

  1. La classe che definisce un metodo di estensione deve essere non-generic, staticenon-nested
  2. Ogni metodo di estensione deve essere un staticmetodo
  3. Il primo parametro del metodo di estensione dovrebbe usare la thisparola chiave.

Se hai inserito la classe in App_Code, allora è destinata ad avere la parola chiave statica nella definizione della classe, ma se la metti in qualsiasi altra cartella, allora va bene usarla come classe normale.
DT,

1
In un caso, avevo usato public static class IQueryable<T> where T : MyBaseClassche genera anche questo errore. La where T : MyBaseClassfrase appartiene ai singoli metodi senza <T>sulla classe statica.
Bron Davies,

1
E se la lezione fosse parziale? Questa soluzione non ha funzionato per me.
Fandango68,

1
Grazie amico, sono stato catturato dal parametro "this"!
Roberto Gata,

1
Fai attenzione che potresti ottenere questo compilatore se hai inavvertitamente convertito la tua classe in un metodo di estensione (secondo il compilatore). Vedi questa risposta per quanto riguarda i metodi statici e questa risposta per quanto riguarda gli thisargomenti del metodo.
Maarten Bodewes,

27

se non si intende avere funzioni statiche, eliminare la parola chiave "this" negli argomenti.


7
Mi stavo grattando la testa per un po 'cercando di capire perché Visual Studio pensava che stessi cercando di trasformare una delle mie classi in un metodo di estensione. Ho scoperto che avevo una thisparola chiave seppellita nelle firme del mio metodo. Rimuovendolo è stato eliminato l'errore.
Fütemire

20

Aggiungi la parola chiave staticalla dichiarazione di classe:

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

16

Prova a cambiare

public class LinqHelper

per

 public static class LinqHelper

15

Modificalo in

public static class LinqHelper

15

Una soluzione per le persone che stanno riscontrando un bug come Nathan:

Il compilatore al volo sembra avere un problema con questo errore del metodo di estensione ... l'aggiunta staticnon mi ha aiutato neanche.

Mi piacerebbe sapere cosa causa il bug?

Ma la soluzione alternativa è scrivere una nuova classe Extension (non nidificata) anche nello stesso file e ricostruire.

Ho pensato che questo thread stia ottenendo abbastanza punti di vista che vale la pena passare la (limitata) soluzione che ho trovato. Molte persone probabilmente hanno provato ad aggiungere "statico" prima di cercare una soluzione su Google! e non ho visto questa soluzione alternativa altrove.


Ho avuto lo stesso problema. Mi sono appena reso conto di aver aggiunto una funzione statica all'interno della classe e ho dimenticato di commentarlo. Questo ha reso statica la mia classe e quindi ha dato questo errore. Controlla se ci sono oggetti statici nella tua classe.
Mahesh,

1

Il metodo di estensione dovrebbe essere all'interno di una classe statica. Quindi aggiungi il tuo metodo di estensione all'interno di una classe statica.

quindi per esempio dovrebbe essere così

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

    }

In che modo differisce dalle risposte fornite anni prima?
Maarten Bodewes,

1

Prova a cambiarlo in classe statica e viceversa. Ciò potrebbe risolvere i problemi con Visual Studio quando si tratta di un falso positivo.


0

Ho riscontrato un problema simile, ho creato una cartella "pippo" e ho creato una "classe" all'interno del pippo, quindi ho ricevuto il suddetto errore. Una soluzione consiste nell'aggiungere "statico" come precedentemente menzionato alla classe che sarà "classe statica pubblica LinqHelper".

La mia ipotesi è che quando si crea una classe all'interno della cartella foo la considera come una classe di estensione, quindi ad essa si applica la seguente regola tra l'altro:

1) Ogni metodo di estensione deve essere un metodo statico

Invia suggerimenti Workaround Se non si desidera statico. La mia soluzione era quella di creare una classe direttamente nello spazio dei nomi e trascinarla nella cartella "pippo".

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.