Type constraints in constructors of generic types

A

anders.forsgren

I have a generic collection looking like this

Set<T> : ICollection<T>
{
// Create set from existing collection.
public Set(ICollection<T> objs) {/* */}

// Add objects to set
public void AddRange(ICollection<T> objs){ /* */ }
}

Now, say I want to create a set for a general type and keep more
specific types in it:

Set<Fruit> fruits = new Set<Fruits>()

List<Fruit> fruitList = new List<Fruit>();
List<Apple> appleList = new List<Apple>();

fruits.AddRange(fruitList); // This is ok of course
fruits.AddRange(appleList); // This is not

This problem can be fixed by modifying the Add() method of my
collection to this

public void AddRange<U>(ICollection<U> obj) where U : T { /* */ }

Now I can do an AddRange(appleList).

So my question, is there any way to have a similar constraint in the
constructor?

class Set<T> : ICollection<T>
{
// Create set from existing collection.
public Set(ICollection<U> objs) : where U : T {/* *}
}

That would allow for this:

List<Apple> apples = new List<Apple>();
Set<Fruit> fruits = new Set(apples);

Thanks
 
J

Jon Skeet [C# MVP]

So my question, is there any way to have a similar constraint in the
constructor?

Unfortunately, constructors themselves cannot be generic - i.e. you can
use the type parameter of the class you're constructing, but no other
ones.

This is just from a brief look at the spec (and a couple of failed
attempts) though - someone may jump in with a counterexample :)
 
A

anders.forsgren

Thanks Jon, I didn't think it would work, but its strange when I can so
easily replicate the behavior of such a constructor using just 3 lines
of code (a static "creator").

public static Set<T> Create<U>(ICollection<U> objs) where U : T
{
Set<T> result = new Set<T>();
result.AddRange(objs);
return result;
}

But the code would be so much nicer if it was allowed as a
constructor....

/Anders
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top