Creating instance of Generic type using parametised constructor
Hi,
Why does the code below not work? I've constrained the T type of the Bar class to be a "Foo" but I still get compiler error "Error 1 'T': cannot provide arguments when creating an instance of a variable type" (beta 2 - 8.0.50215.44). Since I've constrained T to be a class rather than interface, shouldn't I be able to use the Foo(int) constructor? Is there another way of doing the same thing? In my case, Foo is an algorithm (i.e a numerical interpolation scheme) and Bar is a data class which I'd like to associate the algorithm with. It seems like a nice way of doing things but it doesn't work :(
Dave
| |
publicclass Foo { public Foo(int i) { _i = i; } privateint _i; } publicclass Bar<T> where T : Foo,new() { public T Create() { returnnew T(8); } }
|
One of the enhancements I'd like to see to delegates is the ability to specify what constructors T needs to implement like
| | public class Bar<T> where T : Foo, new(), new(int)
|
Unfortunately, as it stands now, the only constructor that you can use is the default constructor. You COULD do the following...
| | public class Foo { public Foo() {} public Foo(int i) { _i = i; } public void Initialize(int i) { _i = i; } private int _i; }public class Bar<T> where T : Foo, new() { public T Create() { T t = new T(); t.Initialize(8); return t; } }
|
but yeah, it's not as pretty as I'd like either.
You can't provide arguments to the constructor of a generic type, because the constraint only specifies T should be of type Foo or derived from Foo. A class derived from Foo could have it's very own constructor, adding or removing arguments.
"the constraint only specifies T should be of type Foo or derived from Foo"
Not true! Did you overlook the "new()" constraint? It specifies that T must implement a constructor with no parameters. The problem is that the "new" constraint doesn't have any options, so we're severely limited in what we can require of T in the way of constructors.
Thanks for the replies, from http://msdn.microsoft.com/msdnmag/issues/03/10/NET/
"The constructor constraint makes it possible for generic code to create instances of the type specified by a type parameter by constraining type arguments to types that implement a public default constructor. At this time, only default or parameterless constructors are supported with the constructor constraint."
The following works as well, but if T were derived from Foo rather than being a Foo it would fail at runtime, doesn't look like you can do T.CreateInstance(8) even though CreateInstance is static, so from what I can gather, the where T:Foo, new() only allows access to Foo's default constructor and non-static methods (i.e. it's really no different to an interface constraint).
| |
public class Foo { private Foo(int i) { _i = i; } public static Foo CreateInstance(int i) { return new Foo(i); } private int _i; } public class Bar<T> where T : Foo, new() { public T Create() { return Foo.CreateInstance(8) as T; } }
|