Mechanic Pig
Mechanic Pig

Reputation: 7736

About Nullable of C# generic parameter

Now I have a SomeClass<T> with a constructor SomeClass(IList<T?> list). But when I use a List<int?> to construct it, the compiler told me:

Cannot resolve constructor SomeClass(System.Collections.Generic.List<System.Nullable<int>>), candidates are: SomeClass(System.Collections.Generic.IList<int>)

I find it means that I have to add "struct" to T's base class list to make sure that T is a value type, but why does this happen and how can make this class avoid using only value type as generic parameter?

Upvotes: 1

Views: 2520

Answers (1)

Olivier Jacot-Descombes
Olivier Jacot-Descombes

Reputation: 112682

@canton7 explains why this does not work in a comment.

You cannot solve this with a constructor, as you will have to introduce a new type parameter and constructors cannot declare type parameters. Therefore I suggest using a factory method.

public class SomeClass<T>
{
    public IList<T> List { get; private set; }

    public static SomeClass<T> Create<U>(IList<Nullable<U>> list)
        where U : struct, T
    {
        return new SomeClass<T> {
            List = list
                .OfType<T>()
                .ToList()
        };
    }
}

Introducing the type parameter U allows us to add a type constraint that is limited to this method, while the type parameter T of the class remains unconstrained.

Note that a null value does not have a type. Therefore, OfType<T>() filters out nulls.

You can test it like this:

var ints = new List<int?> { 1, 2, null, 3 };
var sut = SomeClass<int>.Create(ints);
foreach (int item in sut.List) {
    Console.WriteLine(item);
}

Prints:

1
2
3

Upvotes: 1

Related Questions