C# 2.0: new() constraint on constructors having parameters?

A

Axel Dahmen

Hi,

I've created a generic class having a type argument where I want to use
classes that have a parameterized constructor. I'm calling these constructors
from within the generic class.

Unfortunately I can't use this construct as the C# compiler requires me to
use the new() constraint, but the classes I'm using for the type argument
actually *don't* have a parameterless constructor. They just contain a
constructor having parameters.

Can someone please enlightening me on how to get this to work in C# without
having to implement useless (and invalid) parameterless constructors?

TIA,
Axel Dahmen
 
M

Marc Gravell

new() is the only constructor constraint, so you have three options:

0: revise your design so that you *can* use the default ctor and new()
1: pass in (or otherwise obtain) a factory for creating the objects
2: "wing it"... i.e. hope that the constructor you want exists, and invoke
it anyway

1 might be via either a delegate or an interface, but is a nuicance. 2 gives
less compile-time safety. If this is for moderate usage, then
Activator.CreateInstance has an overload that allows you to pass in
arguments. I also have some .NET 3.5 code for creating constructor delegates
from the type, but you should probably think about the other options
first...

Marc
 
J

Jon Skeet [C# MVP]

Axel Dahmen said:
I've created a generic class having a type argument where I want to use
classes that have a parameterized constructor. I'm calling these constructors
from within the generic class.

Unfortunately I can't use this construct as the C# compiler requires me to
use the new() constraint, but the classes I'm using for the type argument
actually *don't* have a parameterless constructor. They just contain a
constructor having parameters.

In that case the new() constraint is no use to you, and indeed there
aren't any constraints which will do this for you.
Can someone please enlightening me on how to get this to work in C# without
having to implement useless (and invalid) parameterless constructors?

You can't specify a constructor with parameters - you'll have to either
use reflection, or have a separate factory type (which could easily
have a parameterless constructor).
 
C

Christopher Van Kirk

Hi,

I've created a generic class having a type argument where I want to use
classes that have a parameterized constructor. I'm calling these constructors
from within the generic class.

Unfortunately I can't use this construct as the C# compiler requires me to
use the new() constraint, but the classes I'm using for the type argument
actually *don't* have a parameterless constructor. They just contain a
constructor having parameters.

Can someone please enlightening me on how to get this to work in C# without
having to implement useless (and invalid) parameterless constructors?

TIA,
Axel Dahmen

I'm struggling to understand what you're trying to do here. Why not
simply leave off the constraint? I have plenty of generic classes
which have no declared parameterless constructor.
 
J

Jon Skeet [C# MVP]

On Mar 7, 3:39 pm, Christopher Van Kirk <[email protected]>
wrote:

I'm struggling to understand what you're trying to do here. Why not
simply leave off the constraint? I have plenty of generic classes
which have no declared parameterless constructor.

The problem is that there's then no compile-time-safe way of creating
new instances of the type parameter, which I assume is what the OP
wants. However, he wants a compile-time-safe way of doing it *with
parameters*.

Jon
 
C

Cowboy \(Gregory A. Beamer\)

My advice would be to alter the architecture slightly so you can use the
parameterless constructor, even if you have to add one. This may require
re-architecting other parts of your application(s). Teh only other options I
can think of are a) reflection (it works in my mind, not sure in real life,
as you are working from a generic class) or b) fire and forget (which is
dangerous). Mentally, a chain of generics might work, but I have not played
in that playground either.

--
Gregory A. Beamer
MVP, MCP: +I, SE, SD, DBA

*************************************************
| Think outside the box!
|
*************************************************
 
A

Axel Dahmen

Hi lads,

thanks for all your answers and trying to help.

Actually I didn't want to use that constraint in the first place but I get a
compiler error if I omit it. That's because in some of the generic class's
member functions return a new object based on another function's return value:

public T Add(string name, string schemaClassName)
{
return new T(_collection.Add(name, schemaClassName));
}

(I'm actually trying to create a typed version of
System.DirectoryServices.DirectoryEntries)

Axel Dahmen
 
C

Christopher Van Kirk

On Mar 7, 3:39 pm, Christopher Van Kirk <[email protected]>
wrote:



The problem is that there's then no compile-time-safe way of creating
new instances of the type parameter, which I assume is what the OP
wants. However, he wants a compile-time-safe way of doing it *with
parameters*.

Jon

Ahh well, can't have everything I guess.
 
D

Duy Lam

Axel said:
Hi lads,

thanks for all your answers and trying to help.

Actually I didn't want to use that constraint in the first place but I get a
compiler error if I omit it. That's because in some of the generic class's
member functions return a new object based on another function's return value:

public T Add(string name, string schemaClassName)
{
return new T(_collection.Add(name, schemaClassName));
}

(I'm actually trying to create a typed version of
System.DirectoryServices.DirectoryEntries)

Axel Dahmen


I think you can work around with problem by do this: use where and new
keyword. All thing you need is add parameterless constructor and expose
parameters on constructor to public.

public class MyList<T> where T: SomeService,new()
{
......
public T Add(string name,string schemaClassName)
{
T newObject = new T();
T.NewItemIndex = _collection.Add(name, schemaClassName);
}
......
}


class SomeService will have 2 constructor:

public SomeService() { }

public SomeService(int newIndex) { ... }

And it also have an public property NewItemIndex. I assumed that Adđ()
method will return an integer number.

Hope this help.
 
J

Jon Skeet [C# MVP]

Duy Lam said:
I think you can work around with problem by do this: use where and new
keyword. All thing you need is add parameterless constructor and expose
parameters on constructor to public.

The OP's whole problem is that he *doesn't* want to have a
parameterless constructor - he wants to be able to use constructors
which do have parameters, but in a safe way.

Setting properties afterwards has distinct downsides, not least because
it means you can't make the type immutable.
 
A

asdf asdf

Try this,


var t = typeof (T);
var genericObject = (T) Activator.CreateInstance(t, new object[2] {name,
schemaClassName});
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top