There is an AuthenticationBase class in WCF RIA Services. The class definition is as follows:
// assume using System.ServiceModel.DomainServices.Server.ApplicationServices
public abstract class AuthenticationBase<T>
: DomainService, IAuthentication<T>
where T : IUser, new()
What does new() mean in this code?
It's the new constraint.
It specifies that T must not be abstract and must expose a public parameterless constructor in order to be used as a generic type argument for the AuthenticationBase<T> class.
Using the new() keyword requires a default constructor to be defined for said class. Without the keyword, trying to class new() will not compile.
For instance, the following snippet will not compile. The function will try to return a new instance of the parameter.
public T Foo <T> ()
// Compile error without the next line
// where T: new()
{
T newInstance = new T();
return newInstance;
}
This is a generic type constraint. See this MSDN article.
It means that a type used to fill the generic parameter T must have a public and parameterless constructor. If the type does not implement such a constructor, this will result in a compile-time error.
If the new() generic constraint is applied, as in this example, that allows the class or method (the AuthenticationBase<T> class in this case) to call new T(); to construct a new instance of the specified type. There is no other way, short of reflection (this includes using System.Activator, to construct a new object of a generic type.
Related
I am trying to implement the GenericRepository pattern for a Cosmos DB Gremlin Graph API Datasource. So I have:
Added and verified a working Gremlin.Linq library that interfaces w/my Cosmos Graph Database.
Know that in the Generic Repository it implements TEntity where TEntity is a class. I have done the same.
I am now implementing my Generic Repository and want to use a Generic Extension with a clause for a new() so I'm getting the error. What should I do?
Error
The type 'typename' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'parameter' in the generic type or method 'generic'
You are allowed to apply multiple generic constraints when defining a generic type, like so:
public class GenericRepository<TEntity> : IGenericRespository<TEntity>
where TEntity : class, new() //the new() constraint must come last
These constraints mean that in order for a type to be used with GenericRespository<>, it must be both a class (a reference type) and it must provide a public parameter-less constructor. (see docs)
In practice, this means you could have a GenericRepository<object>, but not a GenericRepository<int> because int is a value-type, or GenericRepository<Uri> because although Uri is a class, it does not have a public parameter-less constructor.
public class GenericRespository<T>
where T : class, new()
{
public T Create() => new T();
}
public class Repositories
{
//won't compile, int is a value type;
readonly GenericRespository<int> intRepository = new GenericRespository<int>();
//wont compile, Uri is a class, but no public
//parameterless constructor
readonly GenericRespository<Uri> uriRpository = new GenericRespository<Uri>(); //no public parameterless constructor, doesn't work.
//object is a class and supports new object(), so this works
readonly GenericRespository<object> objectRepository = new GenericRespository<object>(); //works fine
}
These type constraints mean that your GenericRespository<TEntity> will be able to create new TEntity instances on it's own. The real value of this is that you will be able to create your own classes and create a repository of them without writing any additional code.
The correct answer is that Generics can have multiple clauses. So I was able to solve my problem simply by extending the clause (, new()). Now TEntity has to either be a class and a new() which is good for me!
public class ViewModelBaseEx<T> : ViewModelBase where T : class, new()
{
//...........
}
I found a class like this in a sample. In this class what is the meaning of portion "where T : class, new()". what is the use of class, new() in this method definition.
It means that T must be a reference type (normally a class, interface, delegate or array) (but not a struct) and that it must have a public parameterless constructor T() (so this will rule out all the previous with exception of class).
It is a generic type constraint.
It specifies that whatever T is, it must be a reference type (a class) and it must have a public default parameterless constructor (new()).
This allows people to do this:
var x = new T();
Without the new() constraint, that isn't possible.
Basically class, new() are adding constraints.
class means that it should be of type class (structs etc are not allowed)
new() represents that it must have a public constructor which takes no parameters.
It means that T must be a reference (class) type and that it must also have a public default constructor.
See here for more information: http://msdn.microsoft.com/en-us/library/d5x73970.aspx
class here is to constraint T to be of Class only, i.e, cannot be structure and other value types.
new() here is to constraint T has to have an empty constructor.
for more information on type constraint, look at the MSDN: http://msdn.microsoft.com/en-us/library/d5x73970.aspx
"class" basically means that "T" is a class type (could be a struct as well => primitive type). The "new()" syntax means that "T" is a class that has an empty constructor so in your class you could do something like:
var obj = new T();
i want to understand that code. I think T must be IContinentFactory's implemented class but i don't understand to end of the new() keyword.
class AnimalWorld<T> : IAnimalWorld where T : IContinentFactory, new()
{
.....
}
T: new() means that type T has to have a parameter-less constructor.
By that you actually specify that you can write T param = new T(); in your implementation of AnimalWorld<T>
new() mean that T must have default(parameterless) ctor.
Constraints on Type Parameters (C# Programming Guide)
The constraint new() means that the type T must have a public parameterless instance constructor. This includes all value types, but not all classes. No interface or delegate type can have such a constructor. When the new() constraint is present, T can never be an abstract class.
When new() is present, the following code is allowed inside the class:
T instance = new T();
class AnimalWorld<T> : IAnimalWorld where T : IContinentFactory, new()
Here is what the declaration means:
AnimalWorld is a class with a generic type parameter T
The class AnimalWorld must implement IAnimalWorld
The type parameter T must implement IContinentFactory
The class for the type parameter T must have a no-argument constructor (that's what the new is for).
i never use new Constraint because the use is not clear to me. here i found one sample but i just do not understand the use. here is the code
class ItemFactory<T> where T : new()
{
public T GetNewItem()
{
return new T();
}
}
public class ItemFactory2<T> where T : IComparable, new()
{
}
so anyone please make me understand the use of new Constraint with small & easy sample for real world use. thanks
This constraint requires that the generic type that is used is non-abstract and that it has a default (parameterless) constructor allowing you to call it.
Working example:
class ItemFactory<T> where T : new()
{
public T GetNewItem()
{
return new T();
}
}
which obviously now will force you to have a parameterless constructor for the type that is passed as generic argument:
var factory1 = new ItemFactory<Guid>(); // OK
var factory2 = new ItemFactory<FileInfo>(); // doesn't compile because FileInfo doesn't have a default constructor
var factory3 = new ItemFactory<Stream>(); // doesn't compile because Stream is an abstract class
Non-working example:
class ItemFactory<T>
{
public T GetNewItem()
{
return new T(); // error here => you cannot call the constructor because you don't know if T possess such constructor
}
}
In addition to Darin's answer, something like this would fail because Bar does not have a parameterless constructor
class ItemFactory<T> where T : new()
{
public T GetNewItem()
{
return new T();
}
}
class Foo : ItemFactory<Bar>
{
}
class Bar
{
public Bar(int a)
{
}
}
Actual error is: 'Bar' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'T' in the generic type or method 'ItemFactory<T>'
The following would also fail:
class ItemFactory<T>
{
public T GetNewItem()
{
return new T();
}
}
Actual error is: Cannot create an instance of the variable type 'T' because it does not have the new() constraint
The new constraint specifies that any type argument in a generic class declaration must have a public parameterless constructor.
quoted from the official website
You can read new() as if it is an interface with a constructor. Just like that IComparable specifies that the type T has a method CompareTo, the new constraint specifies that the type T has a public constructor.
In your example, the constraint acts on <T> in the class declaration. In the first case, it requires that the generic T object has a default (parameterless) constructor. In the second example, it requires that T should have a default, parameterless constructor and that it must implement the IComparable interface.
Is it possible to construct an object with its internal constructor within a generic method?
public abstract class FooBase { }
public class Foo : FooBase {
internal Foo() { }
}
public static class FooFactory {
public static TFooResult CreateFoo<TFooResult>()
where TFooResult : FooBase, new() {
return new TFooResult();
}
}
FooFactory resides in the same assembly as Foo. Classes call the factory method like this:
var foo = FooFactory.CreateFoo<Foo>();
They get the compile-time error:
'Foo' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'TFooType' in the generic type or method 'FooFactory.CreateFoo()'
Is there any way to get around this?
I also tried:
Activator.CreateInstance<TFooResult>();
This raises the same error at runtime.
You could remove the new() constraint and return:
//uses overload with non-public set to true
(TFooResult) Activator.CreateInstance(typeof(TFooResult), true);
although the client could do that too. This, however, is prone to runtime errors.
This is a hard problem to solve in a safe manner since the language does not permit an abstract constructor declaraton.
The type argument must have a
public parameterless constructor. When used together with other
constraints, the new() constraint must
be specified last.
http://msdn.microsoft.com/en-us/library/d5x73970.aspx
edit: so no, if you use new() constraint, you cannot pass that class, if you don't use new() constraint you can try using reflection to create new instance
public static TFooResult CreateFoo<TFooResult>()
where TFooResult : FooBase//, new()
{
return (TFooResult)typeof(TFooResult).GetConstructor(System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance, null, new Type[] {}, null).Invoke(new object[]{});
//return new TFooResult();
}
There can be few work-arounds as below but I don't think you want to go that way!
Put switch statement inside Factory
that will create the instance based
on type of type parameter.
Each concrete implementation of FooBase will register with FooFactory passing the factory method to create it self. So FooFactory will use the internal dictionary
Extending on the similar line except mapping between type parameter and concrete implementation would be external code (xml file, configuration etc). IOC/DI containers can also help here.
public class GenericFactory
{
public static T Create<T>(object[] args)
{
var types = new Type[args.Length];
for (var i = 0; i < args.Length; i++)
types[i] = args[i].GetType();
return (T)typeof(T).GetConstructor(types).Invoke(args);
}
}