generic class

T

Tony

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
 
R

Richard Blewett

Tony said:
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

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

--
Regards

Richard Blewett
DevelopMentor
http://www.dotnetconsult.co.uk/weblog2
 
M

Marc Gravell

public class Tree said:
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
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
 
J

Jon Skeet [C# MVP]

Tony said:
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.

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.

i.e. any said:
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top