확장 메소드는 제네릭이 아닌 정적 클래스에서 정의해야합니다.


213

오류가 발생했습니다.

확장 메소드는 제네릭이 아닌 정적 클래스에서 정의해야합니다.

라인에서 :

public class LinqHelper

다음은 Mark 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;
    }
}

답변:


309

변화

public class LinqHelper

public static class LinqHelper

확장 메소드를 작성할 때 다음 사항을 고려해야합니다.

  1. 확장 메서드 여야 정의하는 클래스 non-generic, staticnon-nested
  2. 모든 확장 방법은해야합니다 static방법
  3. 확장 메소드의 첫 번째 매개 변수는 this키워드를 사용해야합니다 .

클래스를 App_Code에 배치하면 클래스 정의에 정적 키워드가 있어야하지만 다른 폴더에 배치하면 일반 클래스로 사용하는 것이 좋습니다.
DT

1
어떤 경우에는 public static class IQueryable<T> where T : MyBaseClass이 오류를 생성하는 데 사용했습니다 . where T : MyBaseClass문구없이 각각의 방법에 속하는 <T>정적 클래스.
Bron Davies

1
그러나 수업이 부분적인 경우 어떻게해야합니까? 이 솔루션은 저에게 효과적이지 않았습니다.
Fandango68

1
고마워 친구, 나는 "this"매개 변수에 걸렸다!
Roberto Gata

1
실수로 클래스를 확장 메서드 (컴파일러에 따라)로 변환 한 경우이 컴파일러를 얻을 수 있습니다. 참조 이 답변 정적 방법에 관해서 및 이 답변 관련하여 this메소드 인수를.
Maarten Bodewes

26

정적 함수를 사용하지 않으려면 인수에서 "this"키워드를 제거하십시오.


6
Visual Studio에서 클래스 중 하나를 확장 메서드로 만들려고 생각한 이유를 알아 내려고 잠시 동안 머리를 긁적였습니다. 나는 밖으로 턴은 한 this내 메소드 서명의에에 묻혀 키워드를. 제거하면 오류가 해결되었습니다.
Fütemire 19

20

static클래스 선언에 키워드 를 추가하십시오 .

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

16

바꿔보십시오

public class LinqHelper

 public static class LinqHelper

15

로 변경

public static class LinqHelper

15

Nathan과 같은 버그가 발생하는 사람들을위한 해결 방법 :

즉석 컴파일러가이 확장 메소드 오류에 문제가있는 것 같습니다. 추가 static해도 도움이되지 않습니다.

버그의 원인을 알고 싶습니다.

그러나 해결 방법 은 동일한 파일에 새 중첩 클래스 (중첩되지 않음)를 작성하고 다시 작성하는 것입니다.

이 스레드가 내가 찾은 (제한된) 솔루션을 전달할 가치가있는 충분한 견해를 얻고 있다고 생각했습니다. 대부분의 사람들은 아마도 해결책을 찾기 위해 google-ing하기 전에 '정적'을 추가하려고했습니다! 다른 곳에서는이 해결 방법을 보지 못했습니다.


나는 같은 문제가 있었다. 방금 클래스 내에 정적 함수를 추가하고 주석 처리하는 것을 잊었다는 것을 깨달았습니다. 그래서 내 클래스를 정적으로 만들었 으므로이 오류가 발생했습니다. 클래스에 정적 객체가 있는지 확인하십시오.
Mahesh

1

확장 메소드는 정적 클래스 안에 있어야합니다. 따라서 확장 메소드를 정적 클래스 안에 추가하십시오.

예를 들어 다음과 같아야합니다

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

    }

이것은 몇 년 전의 답변과 어떻게 다릅니 까?
Maarten Bodewes

1

정적 클래스로 변경하고 다시 시도하십시오. 그것은 거짓 긍정 일 때 Visual Studio 불평을 해결할 수 있습니다.


0

비슷한 문제가 발생하여 'foo'폴더를 만들고 foo 내에 "클래스"를 만든 다음 위에서 언급 한 오류가 발생합니다. 한 가지 수정은 앞에서 언급 한 "정적"클래스를 "공용 정적 클래스 LinqHelper"로 추가하는 것입니다.

내 가정은 foo 폴더 안에 클래스를 만들 때 확장 클래스로 간주하므로 다음과 같은 규칙이 적용됩니다.

1) 모든 확장 방법은 정적 방법이어야합니다

해결 방법 정적을 원하지 않는 경우. 해결 방법은 네임 스페이스 바로 아래에 클래스를 만든 다음 "foo"폴더로 드래그하는 것입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.