19

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.

MatthewMartin
  • 32,326
  • 33
  • 105
  • 164

9 Answers9

38

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.

CodesInChaos
  • 106,488
  • 23
  • 218
  • 262
  • 1
    +1, but where T:class is different from where T:SomeClassName, so the first part of the MSDN snippet isn't relevant to the OP. – KeithS Jan 03 '11 at 15:24
  • @CodeInChaos - Excellent answer. I'm curious though, why would anyone specify an actual type (e.g., where T : DataContext). The whole point of generics is to specify the type at runtime. – Randy Minder Jan 03 '11 at 15:54
  • 1
    @Randy Minder - its not more usual with generics to specify the type at *runtime* than regular types. One still usually specifies the type arguments in code. And concrete type constraints are useful whenever the calling code requires a specific base type, be it interfaces, abstract classes or concrete classes. – Peter Lillevold Jan 03 '11 at 16:23
  • 1
    @Randy while it doesn't make sense to use a sealed type as constraint, a non sealed class with virtual or abstract methods still makes sense. And one usually doesn't specify the generic parameter at runtime. It is specified when I specialize the generic, which typically happens in a variable declaration/instantiation. – CodesInChaos Jan 03 '11 at 16:38
  • if we want type argument must have a public constructor with single parameter of string type, then what change do we have to do ? – HotTester Jun 10 '11 at 09:27
  • 1
    @Hot You can't use a generic constraint for that. You're left with reflection (`Activator.CreateInstance`) or some kind of factory delegate. But you won't get compile time checks. – CodesInChaos Jun 10 '11 at 09:29
13

Only allow types T that are derived from or implement DataContext, and have a public constructor that takes no arguments.

Timbo
  • 27,472
  • 11
  • 50
  • 75
  • 1
    `T` must also represent a non-abstract type. This is important because it's legal to call `new T()` when the `new()` constraint has been imposed. Also, if `DataContext` is a class, `T` *can* be `DataContext` itself (rather than derived from it). – Ani Jan 03 '11 at 15:23
9

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).

Oded
  • 489,969
  • 99
  • 883
  • 1,009
6

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.

Matt Kellogg
  • 1,234
  • 8
  • 16
5

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.

Tomas Jansson
  • 22,767
  • 13
  • 83
  • 137
4

where T: DataContext reads as: T must be a (or derived from a) DataContext the ", new()" reads as: must have an parameterless constructor.

Sebastian P.R. Gingter
  • 5,955
  • 3
  • 31
  • 73
2

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.

Pauli Østerø
  • 6,878
  • 2
  • 31
  • 48
2

It's a generics constraint. MSDN has more information on that.

See Constraints on Type Parameters (C# Programming Guide)

Indy9000
  • 8,651
  • 2
  • 32
  • 37
2

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

Dartoxian
  • 750
  • 1
  • 6
  • 10