I saw this code example and was wondering what the purpose of the new() constraint was:
public class Client<T> : IClient where T : IClientFactory, new()
{
public Client(int UserID){ }
}
That's called a "'new' constraint". Here's the documentation on it.
The new constraint specifies that any type argument in a generic class declaration must have a public parameterless constructor. To use the new constraint, the type cannot be abstract.
(Emphasis mine)
Basically, you need it whenever you're creating a new T somewhere in the class, to ensure that you're only able to pass in things which the compiler can create a new instance of.
Client is a collection of T objects, and those T objects must implement the IClientFactory interface and have a public parameterless constructor.
new() means
The type argument must have a public parameterless constructor. When
used together with other constraints, the new() constraint must be
specified last.
Ref Generic Constraints on MSDN
Related
Having these classes:
public interface IDbContextFactory
{
DbContext GetContext();
}
public class Repo<T> : IRepo<T> where T : Entity, new()
{
protected readonly DbContext c;
}
public Repo(IDbContextFactory f)
{
c = f.GetContext();
}
What does the keyword new() (in class Repo<T>) do?
It means that the type T must expose a public, default (i.e. parameterless) constructor. That is, you will be able to construct an instance of T with new T(). It can expose other constructors as well, but this generic constraint makes the default one mandatory.
it means, the entity should have a parameterless public constructor.
see this.
When you use the where keyword on a generic definition you apply a type contraint to the generic paramater. The new() constraint declares that the type, T in this case, must have a default constructor. http://msdn.microsoft.com/en-us/library/sd2w2ew5.aspx
After reading your clarification disguised as an answer I thought I would try and help by clarifying a couple of things.
The code in your orginal question defines an interface that seemes to be used by a disembodied constructor. In between those two denfinitions you have defined a generic class which doesen't seem to do much.
Your question pertains to the generic class and the other two definitions are irrelavent to both the question and the answer.
I am trying to create a generic factory-pattern-like mechanism.
The factory will be like:
public class APlugin<ActionType> where ActionType : IAction
{
// create a new action. Note: ActionType should contain
// an empty constructor
public ActionType CreateAction()
{
return Activator.CreateInstance<ActionType>();
}
}
Descendants of IAction might hide the parameterless constructor and this will cause the factory to fail.
You can ensure class has constructor without arguments by providing generic constraint where T : new(). It will affect type T only, though. Containing class will be unaffected, so you can make sure ActionType in your case has said constructor, but you can't enforce it on any class inheriting from APlugin<T>.
You can't force an empty constructor or any type of constructor on derived types.
Constructors do not get inherited, but do get called.
If not chaining to the base constructor (using the : base() syntax), the default base constructor will be called implicitly.
From Using Constructors on MSDN:
In a derived class, if a base-class constructor is not called explicitly using the base keyword, then the default constructor, if there is one, is called implicitly.
Pretty late but i think this is worth knowing..
You can force constructors with 0 parameters on non-abstract classes. This is a type constraint to use whenever you want to enforce those constraints on a class structure. It requires you to specify the type that implements the interface which might be found disturbing. That's the price if you want some neat type safety.
public interface IEmptyConstructor<TThis> where TThis : IEmptyConstructor<TThis>, new() {}
for example a singleton structure
public abstract class Singleton<TThis> : ISingleton where TThis : Singleton<TThis>, new() { /* some singleton madness */ }
I tried to google this, but all I could find was documents on ordinary class declarations.
public class DataContextWrapper<T> : IDataContextWrapper where T : DataContext, new()
{
}
I see that the class implements IDataContextWrapper, inherits from DataContext and varies with type T depending on how it is instantiated.
I don't know what "where T" or the ", new()" might mean.
It's a generic constraint and restricts what types can be passed into the generic parameter.
In your case it requires that T is indentical to or derived from DataContext and has a default(argumentless) constructor(the new() constraint).
You need generic constraints to actually do something non trivial with a generic type.
The new() constraint allows you to create an instance with new T().
The DataContext constraint allows you to call the methods of DataContext on an instance of T
MSDN wrote:
where T : <base class name>
The type argument must be or derive from the specified base class.
where T : new()
The type argument must have a public parameterless constructor. When used together with other constraints, the new() constraint must be specified last.
Only allow types T that are derived from or implement DataContext, and have a public constructor that takes no arguments.
It's a generic type constraint and specifies constraint on the generic types (for example, only classes, or must implement a specific interface).
In this case, T must be a class that is either DataContext or inherits from it and must have a parameterless public constructor (the new() constraint).
It's a generic type restriction. In this case, T must inherit from DataContext and be a type with a constructor that takes no arguments.
The where keyword is used to constrain your generic type variable, in your case it means that the type T must be a DataContext and must contain a public default constructor.
where T: DataContext reads as: T must be a (or derived from a) DataContext
the ", new()" reads as: must have an parameterless constructor.
It is constraints in the types that can be used as generic. This gives you compiler checks plus the ability to do something meaningful with T.
Ie. new() tells the compiler that T has to have a parameterless constructor. This means that you can instantiate instances of T by writing new T(); and by knowing T is a DataContext as well, you can both make instances of T but also call methods on it.
It's a generics constraint.
MSDN has more information on that.
See Constraints on Type Parameters (C# Programming Guide)
Where is there to place a constraint upon the type of T. The new says that the type T must be instantiable without any parameters. ie T thing = new T();
See more here
This question already has answers here:
What does the keyword "where" in a class declaration do?
(7 answers)
Closed 9 years ago.
In the following piece of code (C# 2.0):
public abstract class ObjectMapperBase< T > where T : new()
{
internal abstract bool UpdateObject( T plainObjectOrginal,
T plainObjectNew,
WebMethod fwm,
IDbTransaction transaction );
}
Inheritor example:
public abstract class OracleObjectMapperBase< T > : ObjectMapperBase< T > where T : new()
{
internal override bool UpdateObject( T plainObjectOrginal,
T plainObjectNew,
WebMethod fwm,
IDbTransaction transaction )
{
// Fancy Reflection code.
}
}
What does the where keyword do?
it is a constraint for generics
MSDN
so the new() constraint says it must have a public parameterless constructor
It specifies a constraint on the generic type parameter T.
The new() constraint specifies that T must have a public default constructor.
You can also stipulate that the type must be a class (or conversely, a struct), that it must implement a given interface, or that it must derive from a particular class.
The where clause is used to specify constraints on the types that can be used as arguments for a type parameter defined in a generic declaration. For example, you can declare a generic class, MyGenericClass, such that the type parameter T implements the IComparable interface:
public class MyGenericClass<T> where T:IComparable { }
In this particular case it says that T must implement a default constructor.
This is a generic type constraint. It means that the generic type T must implement a zero parameter constructor.
The Where keyword is basically a constraint on the objects the class can work on/with.
taken from MSDN "The new() Constraint lets the compiler know that any type argument supplied must have an accessible parameterless constructor"
http://msdn.microsoft.com/en-us/library/6b0scde8(VS.80).aspx
It means the T has to have a public default constructor.
Is it possible for a generic interface's type to be based on a specific parent class?
For example:
public interface IGenericFace<T : BaseClass>
{
}
Obviously the above code doesn't work but if it did, what I'm trying to tell the compiler is that T must be a sub-class of BaseClass. Can that be done, are there plans for it, etc.?
I think it would be useful in terms of a specific project, making sure a generic interface/class isn't used with unintended type(s) at compile time. Or also to sort of self-document: show what kind of type is intended.
public interface IGenericFace<T> where T : SomeBaseClass
What your are referring to is called "Generic Constraints". There are numerous constraints that can be put on a generic type.
Some basic examples are as follows:
where T: struct - The type argument must be a value type. Any value type except Nullable - can be specified. See Using Nullable Types (C# Programming Guide) for more information.
where T : class - The type argument must be a reference type; this applies also to any class, interface, delegate, or array type.
where T : new() - The type argument must have a public parameterless constructor. When used together with other constraints, the new() constraint must be specified last.
where T : <base class name> - The type argument must be or derive from the specified base class.
where T : <interface name> - The type argument must be or implement the specified interface. Multiple interface constraints can be specified. The constraining interface can also be generic.
where T : U - The type argument supplied for T must be or derive from the argument supplied for U. This is called a naked type constraint.
These can also be linked together like this:
C#
public class TestClass<T> where T : MyBaseClass, INotifyPropertyChanged, new() { }
public interface IGenericFace<T> where T : SomeBaseClass
VB
Public Class TestClass(Of T As {MyBaseClass, INotifyPropertyChanged, New})
Public Interface IGenericInterface(Of T As SomeBaseClass)
yes.
public interface IGenericFace<T>
where T : BaseClass
{
}