Các phương thức mở rộng phải được định nghĩa trong một lớp tĩnh không chung chung


213

Tôi đang nhận được lỗi:

Các phương thức mở rộng phải được định nghĩa trong một lớp tĩnh không chung chung

Trên đường dây:

public class LinqHelper

Đây là lớp người trợ giúp, dựa trên mã Mark Gavells. Tôi thực sự bối rối về lỗi này có nghĩa là gì vì tôi chắc chắn rằng nó đã hoạt động tốt khi tôi để nó vào thứ Sáu!

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

Câu trả lời:


309

thay đổi

public class LinqHelper

đến

public static class LinqHelper

Các điểm sau đây cần được xem xét khi tạo phương thức mở rộng:

  1. Lớp định nghĩa một phương thức mở rộng phải là non-generic, staticnon-nested
  2. Mỗi phương thức mở rộng phải là một staticphương thức
  3. Tham số đầu tiên của phương thức mở rộng nên sử dụng thistừ khóa.

Nếu bạn đã đặt lớp trong App_Code thì chắc chắn sẽ có từ khóa tĩnh trong định nghĩa lớp, nhưng nếu bạn đặt nó trong bất kỳ thư mục nào khác thì sử dụng nó như một lớp bình thường.
DT

1
Trong một trường hợp, tôi đã sử dụng public static class IQueryable<T> where T : MyBaseClasscũng tạo ra lỗi này. Các where T : MyBaseClasscụm từ thuộc về các phương pháp cá nhân mà không cần <T>vào lớp tĩnh.
Bron Davies

1
Nhưng nếu lớp học là một phần thì sao? Giải pháp này không hiệu quả với tôi.
Fandango68

1
Cảm ơn bạn thân, tôi đã bắt được thông số "này"!
Roberto Gata

1
Coi chừng bạn có thể có được trình biên dịch này nếu bạn vô tình chuyển đổi lớp của mình thành một phương thức mở rộng (theo trình biên dịch). Xem câu trả lời này liên quan đến các phương thức tĩnh và câu trả lời này liên quan đến các thisđối số phương thức.
Maarten Bodewes

25

nếu bạn không có ý định có các hàm tĩnh, hãy loại bỏ từ khóa "này" trong các đối số.


6
Tôi đã gãi đầu trong một lúc cố gắng tìm hiểu tại sao Visual Studio nghĩ rằng tôi đang cố gắng biến một trong các lớp của mình thành một phương thức mở rộng. Hóa ra tôi đã có một thistừ khóa chôn vùi chữ ký phương thức của mình. Loại bỏ nó đã xóa lỗi.
Fütemire

20

Thêm từ khóa staticđể khai báo lớp:

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

16

Hãy thử thay đổi

public class LinqHelper

đến

 public static class LinqHelper

15

Thay đổi nó thành

public static class LinqHelper

15

Giải quyết vấn đề cho những người đang gặp phải lỗi như Nathan:

Trình biên dịch đang hoạt động dường như có vấn đề với lỗi Phương thức mở rộng này ... việc thêm staticcũng không giúp tôi.

Tôi muốn biết nguyên nhân gây ra lỗi?

Nhưng công việc xung quanh là viết một lớp mở rộng mới (không được lồng) ngay cả trong cùng một tệp và xây dựng lại.

Hình rằng chủ đề này đang nhận được đủ lượt xem mà nó đáng để truyền vào giải pháp (giới hạn) mà tôi tìm thấy. Hầu hết mọi người có thể đã thử thêm 'tĩnh' trước khi google tìm giải pháp! và tôi đã không thấy sửa chữa này xung quanh bất cứ nơi nào khác.


Tôi gặp vấn đề tương tự. Tôi chỉ nhận ra rằng tôi đã thêm một hàm tĩnh trong lớp và quên nhận xét nó. Vì vậy, điều đó làm cho lớp của tôi tĩnh, và do đó đã đưa ra lỗi này. Kiểm tra nếu có bất kỳ đối tượng tĩnh trong lớp của bạn.
Mahesh

1

Phương thức mở rộng phải nằm trong một lớp tĩnh. Vì vậy, vui lòng thêm phương thức mở rộng của bạn bên trong một lớp tĩnh.

vì vậy, ví dụ nó nên như thế này

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

    }

Điều này khác với những câu trả lời được đưa ra nhiều năm trước như thế nào?
Maarten Bodewes

1

Hãy thử thay đổi nó thành lớp tĩnh và trở lại. Điều đó có thể giải quyết khiếu nại hình ảnh khi nó là dương tính giả.


0

Tôi gặp phải một vấn đề tương tự, tôi đã tạo một thư mục 'foo' và tạo một "lớp" bên trong foo, sau đó tôi nhận được lỗi đã nói ở trên. Một cách khắc phục là thêm "tĩnh" như đã đề cập trước đó vào lớp sẽ là "lớp tĩnh công khai LinqHelper".

Giả định của tôi là khi bạn tạo một lớp bên trong thư mục foo, nó coi nó là một lớp mở rộng, do đó quy tắc liên alia sau đây áp dụng cho nó:

1) Mọi phương thức mở rộng phải là một phương thức tĩnh

LÀM VIỆC Nếu bạn không muốn tĩnh. Cách giải quyết của tôi là tạo một lớp ngay dưới không gian tên và sau đó kéo nó vào thư mục "foo".

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.