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
public class Foo private int _i; public class Bar<T> |

Creating instance of Generic type using parametised constructor
bubu
Ahh, yes that works well, I used reflection which works as well but the factory pattern is cleaner. Thanks
public class Foo
{
public Foo(int i)
{
this.i = i;
}
public int i;
}
public class Bar<T>
where T : Foo
{
public T Create(int i)
{
return Activator.CreateInstance(typeof(T), new object[] { i }) as T;
}
}
gssi
public interface IFooFactory<T> where T : Foo
{
T CreateInstance(int i);
}
public class Foo
{
public Foo( int i) {...}
}
public class FooFactory : IFooFactory<Foo>
{
public FooFactory() {...}
public Foo CreateInstance(int i) { return new Foo(i); }
}
public class Bar<T,U>
where T : Foo
where U : IFooFactory<T>, new()
{
public T Create()
{
return fooFactory.Create(8);
}
private U fooFactory = new U();
}
OR
public class Bar<T,U>
where T : Foo
where U : IFooFactory<T>
{
public Bar( U fooFactory)
{
this.fooFactory = fooFactory;
}
public T Create()
{
return fooFactory.Create(8);
}
private U fooFactory = null;
}
HVE
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.
polmau
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.
zoxter
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;
}
}
dsmithwv
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.