ความช่วยเหลือเกี่ยวกับข้อผิดพลาดทั่วไปของ 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;
}

ทำให้เกิดข้อผิดพลาดต่อไปนี้ระหว่างการคอมไพล์:

ประเภท 'T' ต้องเป็นประเภทค่าที่ไม่เป็นโมฆะเพื่อใช้เป็นพารามิเตอร์ 'T' ในประเภททั่วไปหรือวิธีการ 'System.Nullable <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>ไม่ถูกต้อง


สิ่งที่เกี่ยวกับ C # 8 Not nullable flag?
kirin nee

1
@kirinnee: ไม่เพราะNullable<T>ยังต้องTเป็นประเภทค่าที่ไม่เป็นโมฆะไม่ใช่แค่ประเภทที่ไม่เป็นโมฆะ
Jon Skeet

16

Nullable<T>ชนิดนั้นมีข้อ จำกัด ในนั้นที่ต้องใช้Tจะเป็นประเภทค่า ( structใน C #) นั่นเป็นเหตุผลที่คอมไพเลอร์บอกคุณเกี่ยวกับ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

วิธีการทั่วไปของคุณใช้ไฟล์Nullable<T>.

อย่างไรก็ตามคุณไม่ได้ จำกัด ประเภทของTมันดังนั้นจึงอาจกลายเป็นได้Nullable<Form>ซึ่งเห็นได้ชัดว่าไม่ถูกต้อง

คุณต้องเปลี่ยนข้อ จำกัด เพื่อwhere T : struct, IComparableให้แน่ใจว่าTเป็นประเภทค่าเท่านั้น


2

ไม่ใช่คำตอบสำหรับ OP แต่เนื่องจากนี่เป็นสิ่งแรกที่ปรากฏขึ้นใน google สำหรับข้อความแสดงข้อผิดพลาดเดียวกันฉันจึงต้องเพิ่มข้อ จำกัด ในการกำหนดคลาสของฉันแทนที่จะเป็นวิธีการของฉันเช่น

public class MyClass<T> where T : struct
{
    public void MyMethod(T? value)
    {
    }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.