Hello!
I just come to think about one thing and that is
the statement below.
public class Tree<T> where T : IComparable<T>
This is a correct statement and it works as expected.
But now to my question when you use generic classes like this will you
always use the construction with where T : . . .
I mean writing something like
public class Tree<T> : IComparable<T>
generate compile error.
For me it's more or less the same writing
public class Tree<T> where T : IComparable<T>
or
public class Tree<T> : IComparable<T>
It's obvious that type T must implement IComparable and use type T insted of
object in method CompareTo
I can't really see why you have to use the where T.
//Tony
Richard Blewett - 29 Feb 2008 08:04 GMT
> Hello!
>
[quoted text clipped - 21 lines]
>
> //Tony
Well restriction by derivation is not the only constraint you can use - how
about this
class Tree<T> where T: new()
{
}
this says that T must have a default constructor. With your construct you
end up with
class Tree<T> : new()
which I guess would work until you have
class Tree<K, V> : new()
so which generic parameter does the new constraint affect?
Also what about T having to implement a non-generic interface?
class Tree<T> where T : IDisposable
Your construct says something very different
class Tree<T> : IDisposable
in other words the tree rather than T implements IDisposable
The where clause removes ambiguity

Signature
Regards
Richard Blewett
DevelopMentor
http://www.dotnetconsult.co.uk/weblog2
Marc Gravell - 29 Feb 2008 08:20 GMT
> public class Tree<T> where T : IComparable<T>
> This is a correct statement and it works as expected.
Because of the way that constraints tend to propegate, and to supprot
scenarios where a custom comparer (IComparer<T>) is used, it is not all that
common to see "T : IComparable<T>" or "T : IEquatable<T>" in contraints;
instead, a common approach is to use Comparer<T>.Default and
EqualityComparer<T>.Default, which supports all the standard setups
(IComparable<T>, IComparable, IEquatable<T>, object.Equals, etc).
> public class Tree<T> : IComparable<T>
> generate compile error.
Only if you don't do what you promise; if, however, you *do* implement the
interface, the compiler is perfectly happy:
class Tree<T> : IComparable<T> {
public int CompareTo(T other) {
return 0; // daft example
}
}
Marc
Jon Skeet [C# MVP] - 29 Feb 2008 08:24 GMT
> Hello!
>
[quoted text clipped - 9 lines]
> public class Tree<T> : IComparable<T>
> generate compile error.
Well it will if you don't implement the interface.
> For me it's more or less the same writing
> public class Tree<T> where T : IComparable<T>
> or
> public class Tree<T> : IComparable<T>
Well, it may be more or less the same thing to you, but it's completely
different to the compiler.
The first version is restricting the possible values of the type
parameter T.
The second is saying that Tree<T> implements IComparable<T>, i.e. any
Tree<T> can be compared with any other
> It's obvious that type T must implement IComparable and use type T insted of
> object in method CompareTo
>
> I can't really see why you have to use the where T.
Because that's what differentiates between constraining T, and
specifying the base type and interfaces of the type.
Note also that you may have more than one type parameter, and more than
one constraint per type parameter. For instance:
public classs Foo<TKey,TValue> : BaseFoo<TKey,TValue,
IDictionary<TKey,TValue>
where TKey : class, new()
where TValue : struct
This says that:
1) The base classs of Foo<TKey,TValue> is BaseFoo<TKey,TValue>
2) Foo<TKey,TValue> implements IDictionary<TKey,TValue>
3) The TKey type parameter must be a reference type
4) The TKey type parameter must have a parameterless constructor
5) The TValue type parameter must be a non-nullable value type

Signature
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
World class .NET training in the UK: http://iterativetraining.co.uk