एक्सटेंशन विधियों को गैर-जेनेरिक स्थिर वर्ग में परिभाषित किया जाना चाहिए


213

मुझे त्रुटि मिल रही है:

एक्सटेंशन विधियों को गैर-जेनेरिक स्थिर वर्ग में परिभाषित किया जाना चाहिए

रेखा पर:

public class LinqHelper

यहाँ मार्क गैवेल्स कोड के आधार पर सहायक वर्ग है। मैं वास्तव में उलझन में हूँ कि इस त्रुटि का क्या मतलब है क्योंकि मुझे यकीन है कि जब मैं शुक्रवार को इसे छोड़ रहा था तो यह ठीक काम कर रहा था!

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, staticऔरnon-nested
  2. प्रत्येक विस्तार विधि एक staticविधि होनी चाहिए
  3. एक्सटेंशन विधि के पहले पैरामीटर को thisकीवर्ड का उपयोग करना चाहिए ।

यदि आपने क्लास को App_Code में रखा है तो यह क्लास की परिभाषा में स्टेटिक कीवर्ड के लिए बाध्य है, लेकिन यदि आप इसे किसी अन्य फ़ोल्डर में रखते हैं तो इसका सामान्य वर्ग के रूप में उपयोग करने के लिए ठीक है।
डीटी

1
एक मामले में, मैंने उपयोग किया था public static class IQueryable<T> where T : MyBaseClassजो इस त्रुटि को भी उत्पन्न करता है। where T : MyBaseClassवाक्यांश बिना व्यक्तिगत तरीकों पर अंतर्गत आता है <T>स्थिर वर्ग पर।
ब्रॉन डेविस

1
लेकिन क्या होगा अगर वर्ग आंशिक है? यह समाधान मेरे काम नहीं आया।
Fandango68

1
धन्यवाद दोस्त, मैं "यह" पैरामीटर पर पकड़ा गया!
रॉबर्टो गाटा

1
यदि आप अनजाने में अपनी कक्षा को विस्तार विधि (संकलक के अनुसार) में परिवर्तित कर लेते हैं तो आप यह संकलक प्राप्त कर सकते हैं। देखें इस उत्तर स्थिर तरीकों के संबंध में और इस उत्तर के संबंध में thisविधि तर्क।
मार्टेन बोदवेस

26

यदि आपके पास स्थिर कार्य करने का इरादा नहीं है, तो बस तर्कों में "इस" कीवर्ड से छुटकारा पाएं।


6
मैं थोड़ी देर के लिए अपना सिर खुजला रहा था कि विजुअल स्टूडियो ने सोचा कि मैं अपनी कक्षाओं में से एक को विस्तार विधि बनाने की कोशिश कर रहा हूं। यह पता चलता है कि मेरे पास thisमेरे तरीके के हस्ताक्षर थे। इसे हटाने से त्रुटि साफ हो गई।
फ्युटेमेयर

20

staticवर्ग घोषणा में कीवर्ड जोड़ें :

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

16

बदलने की कोशिश करें

public class LinqHelper

सेवा

 public static class LinqHelper


15

नाथन जैसे बग का सामना कर रहे लोगों के लिए एक काम-काज:

ऑन-द-फ्लाई कंपाइलर को यह एक्सटेंशन विधि त्रुटि के साथ एक समस्या है ... जोड़ने staticसे मुझे कोई मदद नहीं मिली।

मैं जानना चाहता हूं कि बग के कारण क्या हैं?

लेकिन काम के आसपास एक ही फाइल में एक नया एक्सटेंशन क्लास (नेस्टेड नहीं) लिखना है और फिर से बिल्ड करना है।

यह पता लगाया कि इस धागे को पर्याप्त विचार मिल रहे हैं कि यह (सीमित) समाधान मुझे मिलने लायक है। ज्यादातर लोगों ने संभवतः समाधान के लिए Google-ing से पहले 'स्टेटिक' जोड़ने की कोशिश की! और मुझे यह काम कहीं और ठीक नहीं लगा।


मेरी भी यही समस्या थी। मुझे बस एहसास हुआ कि मैंने कक्षा के भीतर एक स्थिर फ़ंक्शन जोड़ा और इसे टिप्पणी करना भूल गया। जिससे मेरी कक्षा स्थिर हो गई, और इसलिए मैं यह त्रुटि दे रहा था। जांचें कि क्या आपकी कक्षा में कोई स्थिर वस्तु है।
महेश

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

    }

यह वर्षों पहले दिए गए उत्तरों से कैसे भिन्न है?
मार्टेन बोडेवेस

1

इसे स्टैटिक क्लास और बैक में बदलने की कोशिश करें। यह एक गलत सकारात्मक होने पर शिकायत करने वाले दृश्य स्टूडियो को हल कर सकता है।


0

मुझे एक समान समस्या का सामना करना पड़ा, मैंने एक 'फू' फ़ोल्डर बनाया और फू के अंदर एक "क्लास" बनाया, फिर मुझे उपरोक्त त्रुटि मिली। एक फिक्स "स्टेटिक" जोड़ना है जैसा कि पहले उल्लेख किया गया था कि क्लास "पब्लिक स्टैटिक क्लास लाइनक्लेपर" होगी।

मेरी धारणा यह है कि जब आप foo फोल्डर के अंदर एक क्लास बनाते हैं, तो इसे एक एक्सटेंशन क्लास के रूप में मानते हैं, इसलिए निम्नलिखित इंटर एलिया नियम इस पर लागू होता है:

1) प्रत्येक विस्तार विधि एक स्थिर विधि होनी चाहिए

यदि आप स्थिर नहीं चाहते हैं तो काम करें। मेरा वर्कअराउंड नेमस्पेस के तहत सीधे एक क्लास बनाना था और फिर इसे "फू" फोल्डर में ड्रैग करना था।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.