C # जेनरिक त्रुटि में सहायता करें - "टाइप 'T' एक गैर-अशक्त मान होना चाहिए"


100

मैं C # में नया हूं और समझ नहीं पा रहा हूं कि निम्न कोड क्यों काम नहीं करता है।

public static Nullable<T> CoalesceMax<T>(Nullable<T> a, Nullable<T> b) where T : IComparable
{
    if (a.HasValue && b.HasValue)
        return a.Value.CompareTo(b.Value) < 0 ? b : a;
    else if (a.HasValue)
        return a;
    else
        return b;
}

// Sample usage:
public DateTime? CalculateDate(DataRow row)
{
    DateTime? result = null;
    if (!(row["EXPIRATION_DATE"] is DBNull))
        result = DateTime.Parse((string)row["EXPIRATION_DATE"]);
    if (!(row["SHIPPING_DATE"] is DBNull))
        result = CoalesceMax(
            result
            DateTime.Parse((string)row["SHIPPING_DATE"]).AddYears(1));
    // etc.
    return result;
}

यह संकलन के दौरान निम्नलिखित त्रुटि देता है:

जेनेरिक प्रकार या विधि 'System.Nullable <T>' में पैरामीटर 'T' के रूप में उपयोग करने के लिए 'T' एक गैर-अशक्त मान प्रकार होना चाहिए।

1
कंपाइलर एरर आपको फंक्शन डेफिनिशन की लाइन देता है क्योंकि यहीं पर एरर होता है।
SLAKs

जवाबों:


181

आपको एक T : structबाधा जोड़ने की जरूरत है :

public static Nullable<T> CoalesceMax<T>
    (Nullable<T> a, Nullable<T> b) where T : struct, IComparable

अन्यथा C # का Nullable<T>मतलब क्या है, यह जानने की कोशिश करेंगे , और यह महसूस करेंगे कि इसमें पहले से Nullable<T>ही बाधा नहीं है। दूसरे शब्दों में, आप कॉल करने का प्रयास कर सकते हैं:

CoalesceMax<string>(...)

जो Nullable<string>मान्य नहीं होगा , जैसा कि मान्य नहीं है।


16

इस Nullable<T>प्रकार पर एक बाधा होती है जिसके Tलिए एक मूल्य प्रकार ( structC # में) होना आवश्यक है। इसीलिए कंपाइलर Nullable<T>आपके फंक्शन या उस फंक्शन की कॉल साइट के बारे में नहीं बल्कि आपको बता रहा है - यह वह Nullableवर्ग है जो त्रुटि का मूल कारण है, इसलिए यह वास्तव में अधिक मददगार है कि यदि कंपाइलर ने सिर्फ आपके फंक्शन को बताया और कहा "यह सही नहीं है, इसे ठीक करो!" (कल्पना करें कि यदि CoalesceMaxकई जेनरिक का उपयोग किया गया है, और उनमें से केवल एक पर बाधा का उल्लंघन किया गया है - यह जानना अधिक उपयोगी है कि किस सामान्य से इसकी बाधा टूटी थी, यह जानने के लिए कि एक या अधिक बाधाएं CoalesceMaxटूट गई थीं)।

समाधान यह है कि आप Tऔर उनके Tसंगत को एक ही बाधा को पेश करके बनाया जाए। यह structबाधा को जोड़कर किया जाता है , जो सभी इंटरफ़ेस / नई बाधाओं से पहले आना चाहिए:

public static Nullable<T> CoalesceMax<T>(Nullable<T> a, Nullable<T> b) where T : struct, IComparable{
  ...
}

6

आपकी सामान्य विधि a का उपयोग कर रही है Nullable<T>

हालाँकि, आप इस प्रकार का दबाव नहीं बना रहे हैं T, इसलिए यह समाप्त हो सकता है Nullable<Form>, जो स्पष्ट रूप से अमान्य है।

आपको where T : struct, IComparableयह सुनिश्चित करने के लिए बाधा को बदलने की जरूरत है कि Tकेवल एक मूल्य प्रकार हो सकता है।


2

ओपी के लिए बिल्कुल जवाब नहीं है, लेकिन चूंकि यह पहली चीज थी जो एक ही त्रुटि संदेश के लिए Google पर पॉप अप हुई थी, मुझे अपनी विधि के बजाय अपनी कक्षा की परिभाषा पर बाधा को जोड़ना था, जैसे।

public class MyClass<T> where T : struct
{
    public void MyMethod(T? value)
    {
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.