简体   繁体   中英

How to make Generic parameter T Nullable in C#?

I'm creating a generic method which should be able to return null .

As an example I've created this method GetSecondSmallest(List<T>) below. This function loops through all of the IComparable items and returns the second smallest item if possible. If this item does not exist it returns null .

public T? GetSecondSmallest<T>(List<T> items) where T : Nullable, IComparable
{
    if (items.Count == 0) return null;

    T smallest = items[0];
    T? secondSmallest = null;

    // Find second smallest by looping through list

    return secondSmallest;
}

Two example usages of this method would be:

GetSecondSmallest(new List<int> {4, 2, 3, 1, 6, 8}) // Should return 2
GetSecondSmallest(new List<MyComparable> {new MyComparable('x')}) // Should return null

When you try to compile this code you'll see what the problem is here:

Error CS0717 'Nullable': static classes cannot be used as constraints

How can I make this method return either an instance of T or null ?


EDIT : I have already seen this question , but this does not answer my question, because in my situation the parameter is also generic, and should be Nullable . So the provided answers there aren't applicable.

You can't narrow T down as nullable or an object. You have to make two methods, one for T and one for T? .

public T? GetSecondSmallestAsNullable<T>(List<T> items) where T : struct
{
    return null;
}

public T GetSecondSmallestAsClass<T>(List<T> items) where T : class
{
    return null;
}

Use a wrapper class such as Tuple to wrap the resulting value. In the example below, null is returned if there is no second smallest item, otherwise a Tuple is returned with the second smallest value.

public static void Main()
{
    var result1 = GetSecondSmallest(new List<int>
    {
    4, 2, 3, 1, 6, 8
    }); // Should return 2

    var result2 = GetSecondSmallest(new List<MyComparable>
    {
    new MyComparable('x')
    }); // Should return null

    Console.WriteLine("result1=" + result1.Item1);
    Console.WriteLine("result2 == null: " + (result2 == null));
}

public static Tuple<T> GetSecondSmallest<T>(List<T> items)where T : IComparable
{
    return items.Skip(1).Select(v => Tuple.Create(v)).FirstOrDefault();
}

Change the return type to Nullable, and call the method with the non nullable parameter

Simple example:

static void Main(string[] args)
{
    int? i = GetValueOrNull<int>(null, string.Empty);
}


public static Nullable<T> GetValueOrNull<T>(DbDataRecord reader, string columnName) where T : struct
{
    object columnValue = reader[columnName];

    if (!(columnValue is DBNull))
        return (T)columnValue;

    return null;
}

Nullable type as a generic parameter possible?

UPD

Like this:

public Nullable<T> GetSecondSmallest<T>(List<T> items) where T : IComparable
{
    if (items.Count == 0) return null;

    Nullable<T> smallest = items[0];
    Nullable<T> secondSmallest = null;

    // Find second smallest by looping through list

    return secondSmallest;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM