I'm trying to create a new object of type T via its constructor when adding to the list.
I'm getting a compile error: The error message is:
'T': cannot provide arguments when creating an instance of a variable
But my classes do have a constructor argument! How can I make this work?
public static string GetAllItems<T>(...) where T : new()
{
...
List<T> tabListItems = new List<T>();
foreach (ListItem listItem in listCollection)
{
tabListItems.Add(new T(listItem)); // error here.
}
...
}
in .Net 3.5 and after you could use the activator class:
This will not work in your situation. You can only specify the constraint that it has an empty constructor:
What you could do is use property injection by defining this interface:
Then you could alter your method to be this:
The other alternative is the
Func
method described by JaredPar.You need to add where T: new() to let the compiler know that T is guaranteed to provide a default constructor.
If you have access to the class you're going to use, you can use this approach which I used.
Create an interface that has an alternative creator:
Make your classes with an empty creator and implement this method:
Now use your generic methods:
If you don't have access, wrap the target class:
I sometimes use an approach that resembles to the answers using property injection, but keeps the code cleaner. Instead of having a base class/interface with a set of properties, it only contains a (virtual) Initialize()-method that acts as a "poor man's constructor". Then you can let each class handle it's own initialization just as a constructor would, which also adds a convinient way of handling inheritance chains.
If often find myself in situations where I want each class in the chain to initialize its unique properties, and then call its parent's Initialize()-method which in turn initializes the parent's unique properties and so forth. This is especially useful when having different classes, but with a similar hierarchy, for example business objects that are mapped to/from DTO:s.
Example that uses a common Dictionary for initialization:
If you simply want to initialise a member field or property with the constructor parameter, in C# >= 3 you can do it very easier:
This is the same thing Garry Shutler said, but I'd like to put an aditional note.
Of course you can use a property trick to do more stuff than just setting a field value. A property "set()" can trigger any processing needed to setup its related fields and any other need for the object itself, including a check to see if a full initialization is to take place before the object is used, simulating a full contruction (yes, it is an ugly workaround, but it overcomes M$'s new() limitation).
I can't be assure if it is a planned hole or an accidental side effect, but it works.
It is very funny how M$ people adds new features to the language and seems to not do a full side effects analysis. The entire generic thing is a good evidence of this...