A Generic Constraint Question

Here's a question I get fairly frequently: the user desires to create a generic type Bar<T> constrained such that T is guaranteed to be a Foo<U>, for some U.

The way they usually try to write this is

class Bar<T>  where T : Foo<T> {...

which of course then does not work. The user discovers this when they type

 new Bar<Foo<string>>()

and get an error stating that the constraint has been violated. Which it certainly has. The constraint says that T must be Foo<T>, so therefore string must be Foo<string>, which clearly it is not.

There are a few ways to solve this problem. One is to simply introduce a new type parameter:

 class Bar<T, U> where T : Foo<U>

this means that you now have some redundancy:

new Bar<Foo<string>, string>()

But let's stop and think for a moment about what the user desired in the first place. Suppose there were a way to specify what we sometimes call a "mumble type" on the C# design team:

class Bar<T>  where T : Foo<?> {...

Think about the consequences of that on the caller side; the compiler could verify that new Bar<Foo<string>>() was legal. But what could the compiler verify on the callee side?

class Bar<T>  where T : Foo<?> {
   public void Blah(T t) {

t dot what? We don't know anything about T except that it is Foo<something>. What methods, properties, fields or events of Foo could we access? Only those that in no way consume the generic type, which seems like precious little. If Foo had a whole lot of stuff that wasn't generic, why was it made generic in the first place?

But this then leads to an insight; if the user owns the Foo<T> class, then they could do precisely that:

public abstract class FooBase
  private FooBase() {} // Not inheritable by anyone else
  public class Foo<U> : FooBase {...generic stuff ...}
  ... nongeneric stuff ...

public class Bar<T> where T: FooBase { ... }
new Bar<FooBase.Foo<string>>()

and now everyone is happy. The compiler restricts the construction of Bar to FooBase on the caller side. The compiler ensures that every runtime instance of FooBase is an instance of Foo<T>. And the compiler allows the callee side to use all the non-generic methods on FooBase.

Personally, I would go for the first solution myself. But it's edifying to try and find additional solutions, even if they are a bit odd.

Comments (23)

  1. Frisky says:

    I like where this is going:

    Ignoring the typing issue (the meat of you example) if the type U in the generic Foo<>, what if I could instead say?

      class Bar<T> where T : Foo<U> where U : new


      class Bar<T> where T : (Foo<U> : where U : new)

  2. Richard says:

    I think I’m missing why anyone would want the original interface. Why not implement it like this (in C++, but I’m sure the translation is straightforward):

    template<typename U>

    class Bar {

     typedef Foo<U> T;

     // …


    (of course, in C++, you could only declare the base template, then specialize for Bar<Foo<U>> to get the desired effect, but the upshot would be the same — you’d get U as a template parameter instead of T)

  3. Joren Vermijs says:

    Minor, but I think that should be ‘Foo<U> : FooBase’ in stead of ‘Foo<U> : Foo’.

    I’d also use the first solution, as it immediately, without indirection, expresses the programmer’s intention. A bit of redundancy is not so bad compared to needing how exactly Foo and FooBase relate.

    Wouldn’t it be possible to extend type inference a bit to allow you to specify only Foo<string> and have the compiler infer U = string by itself? You would of course need syntax to specify which types you’re trying to have inferred; that might be something like ‘new Bar<Foo<string>,>’ (note the comma).

  4. Eric Lippert says:

    That was a typo. Fixed. Thanks!

    And yes, we have considered adding "mumble types" to the language in a variety of contexts; this would be a possible context in which "new Bar<Foo<string>, ?>" might make sense.  However, we have no plans to add them to the language any time soon.

  5. TwelveBaud says:

    Unless I’m mistaken, it is possible to do this in Java right now with their mumble type declarations:

    class Bar<T extends Foo<? extends U>> { … }

    You could use any generic methods of Foo as though the type parameter was U, even if the actual type parameter is some subclass of U.

  6. Erik says:

    A slightly related, but still unrelated question: Why are there no typedefs in C#. Sometimes it would be useful to  say something like

    class X<T> {

     class Y<T> {


     internal typedef Dictionary<T, IEnumerable<Y<T>>> MySensibleName;


    I realize public and protected typedefs would be hard since all callers would need to be recompiled if the typedef was changed, but what would be the problem with internal and private ones?

  7. Mark Sowul says:

    I hate Java’s generics with a passion (type-erasure is horrible) but I really do like the wildcard type constraint stuff as Andrew Cook demonstrated.  I also like the call-site variance.


    rik: you can use the using statement to alias things.

    using Dictionary<T, IEnumerable<Y<T>>>  = MySensibleName

    It is unfortunate that it uses the same using keyword.

  8. Eric Lippert says:

    Andrew Cook: Actually, what you are describing there is how Java does contravariance/covariance. See my blog archive on this subject for how we are considering doing this in a future version of C#.

    Mark: Call site variance is interesting, but kind of strange. We are probably not going to support it in C#.

    Mark, Erik:  You can use "using" as a form of typedef, but not in a generic manner.  That is, you cannot say:

    using Frib.Frab.Blah.Abc.Def<T> = MyDef<T>

    to define a "family" of typedefs. Though I agree that it would be useful, unfortunately this did not make the short list of features that we are going to do for the next version of C#.

  9. Erik says:

    I do agree that using is possible, but it only works in one file. Sometimes in those cases, I derive a new class

    internal class MySensibleName : Dictionary<T, IEnumerable<Y<T>> {}

    Does anyone have a better idea?

  10. MKane91301 says:

    Generally when I’ve found myself in the situation of having a generic type for implementation reasons but callers aren’t interested in the type parameter(s), I use a non-generic or less generic interface rather than base class to abstract away the type parameter(s) the caller doesn’t care about, so IFoo instead of FooBase.

    As for mumble types and typedefs, I find where I want the abbreviation is not in defining the generic type but in using it. So for example if I have T<U,V> where U : IComparer<V>, I hate having to write new T<MyStringComparer, string>. It’s like preschool programming: the compiler says "So we know that MyStringComparer implements IComparer<string>, so that means V must be…….?" and we have to shout out "string!" and the compiler says "Very good! Now let’s all write string right there. Has everybody done that now?"

    I would rather be able to write something like T<U, infer V> where U : IComparer<V> or to have public interface IComparer<T> { typedef T ComparandType; … } and then T<U, ?> where U : IComparer<?> and then refer to ? as U.ComparandType. In either case, even though the CLR would still see T`2, the compiler would apply the syntactic sugar when I write T<MyStringComparer> and emit T`2[MyStringComparer, System.String].

  11. MKane91301 says:

    I find I am frequently defining empty classes and interfaces to give a name to the most frequently used specializations of generic types. This is where I would love a public typedef. It would just be a little metadata that creates a public alias. To the consuming assembly it would look just like a type and the runtime would treat it the same way the C++ compiler treats typedefs.

  12. David Nelson says:


    I also would like to be able to do away with "preschool programming". In the business layer of one of my applications I have a large set of classes with two generic parameters where one of the types is inferable but the compiler requires it to be written out anyway.

    I also would like to see at least internal typedefs. I don’t need them all that often, but I do find myself missing them occasionally.

  13. Eric Lippert vient de publier un excellent post sur les génériques . L’idée est de pouvoir faire ceci

  14. Larry Lard says:

    > Generally when I’ve found myself in the situation of having a generic type for implementation reasons but callers aren’t interested in the type parameter(s), I use a non-generic or less generic interface rather than base class to abstract away the type parameter(s) the caller doesn’t care about, so IFoo instead of FooBase.

    One thing that used to come up frequently on the newsgroup (when I still had time to read) was people trying to find some declaration which captured the spirit of

    void Baz(List<anything> list)

    We would lead them socratically to the realisation that the type that expressed the idea ‘what behaviour is common to all List<anything>s’ best is IList.

  15. Pop Catalin says:

    You have typedef in C# it’s called ‘type alias’ :

    try this:

    using System;

    using IntList = System.Collections.Generic.List<int>;

    class Program


    static void Main(string[] args)


           IntList list = new IntList();





  16. [ICR] says:

    Typical, I’ve never needed to do this and then it came up twice today!

  17. Tanveer Badar says:

    I think the FooBase solution should be the one everyone follows. Same thing happens in C++ std lib, basic_ios (a template) inherits from ios_base (non-template) which contains all the stuff which is agonistic to templates.

  18. TimNew says:

    I think this problem is caused by the C# generic syntax does not support the cascading generic description.

    In fact, in declaration "class Bar<T>  where T : Foo<T>", there are 3 T. And the 1st, and 3rd ones are the same meaning. But the 2nd T, I think it means something else~

    So I think this problem is caused by the confusion of the meanings of generic parameter T!

  19. Steve Cooper says:

    I’m having exactly this problem — anyone figure out how I might do this…?

    Maybe<T> is a class which may or may not contain a value. Think of Nullable<T> that can contain reference types, or like the option monad.

    T might be a list, say List<U>. If it is, then we’ve got a type like "This object might contain a list of U’s": the type should match "Maybe<T> where T:List<U>"

    I’d like to create an extension method called .ToList(), which gives me the list if there is one, or the empty list otherwise.

    So I’m trying the code below, and it compiles, but the method isn’t showing up on autocomplete;

       public static class OptionMonad


           public static List<U> ToList<T, U>(this Maybe<T> maybeList) where T : List<U>


               return (maybeList.Success ? maybeList.Value : new List<U>());



    Any ideas why this doesn’t show up on autocomplete?

  20. Eric Lippert says:

    I just tried your code on my machine and I get intellisense just fine for this extension method. Can you give me a small, detailed, specific repro scenario?  Feel free to email it to me, Eric@Lippert.com.

  21. Eric Lippert says:

    > In fact, in declaration "class Bar<T>  where T : Foo<T>", there are 3 T. And the 1st, and 3rd ones are the same meaning. But the 2nd T, I think it means something else.

    Why do you think that?  All three T’s name the same type parameter. The first one is the introduction of the name of the parameter. the second describes a constraint on the parameter, and the third is a use of the name as a type argument to Foo.

  22. Rather than place the links to the most recent C# team content directly in Community Convergence, I have

  23. holatom says:

    let’s have Foo<T> like this:

           class Foo<T>


               public static void StaticMethod(T Value)




               public void Method(T Value)





    Why than instead of for example this:

           class Bar<T, U> where T : Foo<U>


               public static void InvokeMethodsOnFoo(T foo, U value)






    make Bar like this:

           class Bar<U>


               public static void InvokeMethodsOnFoo(Foo<U> foo, U value)






    with only one generic parameter (of course it requires change in all Bar’s methods).

Skip to main content