views:

51

answers:

2

Is it not supported, is it supported but I have to do some tricks?

Example:

class Foo
{
  public Foo<T1,T2>(Func<T1,T2> f1,Func<T2,T1> f2)
  {
     ...
  }
}

the generics are only used in constructor, there is no field/property depended on them, I use it (generics) to enforce the type correlation for f1 and f2.

Remark: I found the workaround -- static method Create, but anyway I am curious why I have problem with straightforward approach.

+6  A: 

No, generic constructors aren't supported in either generic or non-generic classes. Likewise generic events, properties and finalizers aren't supported.

Just occasionally I agree it would be handy - but the syntax would look pretty awful. For example, suppose you had:

public class Foo<T> {}

public class Foo
{
    public Foo<T>() {}
}

What would

new Foo<string>()

do? Call the generic constructor of the non-generic class, or the normal constructor of the generic class? You'd have to differentiate between them somehow, and it would be messy :(

Likewise, consider a generic constructor in a generic class:

public class Foo<TClass>
{
    public Foo<TConstructor>() {}
}

How would you call the constructor? Hopefully we can all agree that:

new Foo<string><int>()

is pretty hideous...

So yes, semantically it would be occasionally useful - but the resulting ugliness counterbalances that, unfortunately.

Jon Skeet
You could get around the same-named class problem by not allowing a generic and non-generic class with the same name (seriously, does C# allow this?). For the generic constructor of the generic class, I don't think it's too hideous -- it's just higher order genericity.
Peter Alexander
One remark -- constructor in generic class is generic, because the class is generic. However (taking your answer) it cannot specify **extra** generic arguments. Thank you for very good examples!
macias
@Peter: No, the samed-named class problem isn't a problem, because although you *can* "overload" classes by type arity, there's no ambiguity. See `Tuple` for an example of that.
Jon Skeet
@macias: I don't consider the constructor to be generic, precisely *because* it doesn't introduce any extra type parameters. Would you consider `List<T>.IndexOf` to be a generic method, just because it's in a generic type?
Jon Skeet
Peter -- actually the class name overloading is useful, because you put in non-generic class all static methods. In C++ I always have such odd pairs MyClass<...> and MyClassFactory. In C# you can have several Tuple classes and the call Tuple.Create(5,"hello",4.5) is "clean".
macias
@Jon, yes, I consider such method as generic. After all they all work on generic types -- thus they are generic. The non-generic one would be Count -- because it does not depend on generic type.
macias
+2  A: 

Generic constructors are not supported, but you can get around this by simply defining a generic, static method that returns a new Foo.

Peter Alexander