There is something that I don't understand about .NET Generics. I have code
like the following:

public class A
{
private string _paramOne;
private string _paramTwo;
public A(string paramOne, string paramTwo)
{
_paramOne = paramOne;
_paramTwo = paramTwo;
}
}

public class GenericA<T> where T : new()
{
public GenericA(string paramOne, string paramTwo)
{
new T(paramOne, paramTwo);
}
}

static void Main(string[] args)
{
GenericA<A> instance = new GenericA<A>("paramOne", "paramTwo");
}


In trying to get the strings to the type specified by the generic type
parameter I get numerous errors mainly focusing on the fact that I either
must define a parameterless construtor or I cannot use parameters in a
constructor. So my question is two fold. How do I get the arguments on the
GenericA<A> constructor to the A class? And, when and how is the type A
instantiated and constructed.

Thank you.

Kevin Burton

Re: Generics and constructors. by Carl

Carl
Sun Jan 07 22:23:16 CST 2007

Kevin Burton wrote:
> There is something that I don't understand about .NET Generics. I
> have code like the following:
>
> public class A
> {
> private string _paramOne;
> private string _paramTwo;
> public A(string paramOne, string paramTwo)
> {
> _paramOne = paramOne;
> _paramTwo = paramTwo;
> }
> }
>
> public class GenericA<T> where T : new()
> {
> public GenericA(string paramOne, string paramTwo)
> {
> new T(paramOne, paramTwo);
> }
> }
>
> static void Main(string[] args)
> {
> GenericA<A> instance = new GenericA<A>("paramOne",
> "paramTwo"); }
>
>
> In trying to get the strings to the type specified by the generic type
> parameter I get numerous errors mainly focusing on the fact that I
> either must define a parameterless construtor or I cannot use
> parameters in a constructor. So my question is two fold. How do I get
> the arguments on the GenericA<A> constructor to the A class? And,
> when and how is the type A instantiated and constructed.

You can't. .NET generics constructor constraint only supports a default
constructor - there's no way to invoke any other constructor on the generic
type parameter. The closest you can come is to define an interface and use
two-phase construction:

public interface IStringInit
{
void Init(string p1, string p2);
}

public class X<T> where T: IStringInit, new()
{
public X(string p1, string p2)
{
T t = new T();
t.Init(p1,p2);
}
}

public class A : IStringInit
{
private string _paramOne;
private string _paramTwo;
public void Init(string paramOne, string paramTwo)
{
_paramOne = paramOne;
_paramTwo = paramTwo;
}

static void Main(string[] args)
{
X<A> instance = new X<A>("paramOne", "paramTwo");
}
}


.NET Generics are a great addition, but the need to be fully typesafe at
compile time puts huge limitations on what you can do with them.

-cd



Re: Generics and constructors. by Ben

Ben
Wed Jan 10 14:07:46 CST 2007


>> In trying to get the strings to the type specified by the generic type
>> parameter I get numerous errors mainly focusing on the fact that I
>> either must define a parameterless construtor or I cannot use
>> parameters in a constructor. So my question is two fold. How do I get
>> the arguments on the GenericA<A> constructor to the A class? And,
>> when and how is the type A instantiated and constructed.
>
> You can't. .NET generics constructor constraint only supports a default
> constructor - there's no way to invoke any other constructor on the
> generic type parameter. The closest you can come is to define an
> interface and use two-phase construction:
>

The factory pattern seems to be appropriate here. You could always do
something like have a static method that creates the object, and in the type
initializer of your generic class, use reflection to get the MethodInfo and
create a delegate. Then you only have the overhead once per class.

class A
{
private A(string one, string two) { }
public static Create(string one, string two) { return new A(one, two); }
}

class Generic<T>
{
delegate T Factory(string one, string two);
static Factory Constructor;
static Generic()
{
Constructor = Delegate.Create(typeof(Factory), typeof(T), "Create");
}

//instead of T t = new T("A", "B")
T t = Constructor("A", "B");
}

The downside to this is that it's not compile-time checked list generic type
constraints, and calling through a delegate might be a tiny bit slower than
a generic method call. The static constructor is going to be a hog, but it
only runs once for each T you use. You might use lazy initialization if you
don't create new instances of every different T.



Re: Generics and constructors. by Ben

Ben
Wed Jan 10 14:15:38 CST 2007


"Ben Voigt" <rbv@nospam.nospam> wrote in message
news:OuKUeLPNHHA.3952@TK2MSFTNGP02.phx.gbl...
>
>>> In trying to get the strings to the type specified by the generic type
>>> parameter I get numerous errors mainly focusing on the fact that I
>>> either must define a parameterless construtor or I cannot use
>>> parameters in a constructor. So my question is two fold. How do I get
>>> the arguments on the GenericA<A> constructor to the A class? And,
>>> when and how is the type A instantiated and constructed.
>>
>> You can't. .NET generics constructor constraint only supports a default
>> constructor - there's no way to invoke any other constructor on the
>> generic type parameter. The closest you can come is to define an
>> interface and use two-phase construction:
>>
>
> The factory pattern seems to be appropriate here. You could always do
> something like have a static method that creates the object, and in the
> type initializer of your generic class, use reflection to get the
> MethodInfo and create a delegate. Then you only have the overhead once
> per class.
>
> class A
> {
> private A(string one, string two) { }
> public static Create(string one, string two) { return new A(one,
> two); }
> }
>
Just realized, when using a delegate, there's absolutely zero reason not to
lazily initialize:

> class Generic<T>
> {
> delegate T Factory(string one, string two);
static Factory Constructor = GetFactoryFunctor;
static T GetFactoryFunctor(string one, string two)
{
Constructor = Delegate.Create(typeof(Factory), typeof(T), "Create");
return Constructor(one, two);
}
>
> //instead of T t = new T("A", "B")
> T t = Constructor("A", "B");
> }
>
> The downside to this is that it's not compile-time checked list generic
> type constraints, and calling through a delegate might be a tiny bit
> slower than a generic method call. The static constructor is going to be
> a hog, but it only runs once for each T you use. You might use lazy
> initialization if you don't create new instances of every different T.
>