By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
457,933 Members | 1,574 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 457,933 IT Pros & Developers. It's quick & easy.

Why is class Sample<T> where T : Stream, class ILLEGAL

P: n/a
Would someone explain why this declaration is illegal: class Sample<T>
where T : Stream, class
Nov 3 '08 #1
Share this Question
Share on Google+
36 Replies


P: n/a
On Nov 3, 1:54*pm, puzzlecracker <ironsel2...@gmail.comwrote:
Would someone explain why this declaration is illegal: class Sample<T>
where T : Stream, class
They are taken from C# In depth book
And a few more that are also illegal, and I don't understand why
(compiler is less than helpful).

class Sample<Twhere T : Stream, class

class Sample<Twhere T : new(), Stream

class Sample<T,Uwhere T : struct where U : class, T

class Sample<T,Uwhere T : Stream, U : IDisposable
Nov 3 '08 #2

P: n/a
You can restrict the generic implementation by either a base type or
value/reference type. Not both.

Stream is already a class. So, T will be a reference type (class) if you
restrict T to be a Stream. So, basically you are trying to say class 2
times.
puzzlecracker wrote:
Would someone explain why this declaration is illegal: class Sample<T>
where T : Stream, class
Nov 3 '08 #3

P: n/a
Any 'class' or 'struct' constraints should come first but why are you adding
an 'all classes' constraints if you would like to use this generic class
with Stream and derivative classes?
--
Stanimir Stoyanov
http://stoyanoff.info

"puzzlecracker" <ir*********@gmail.comwrote in message
news:45**********************************@z6g2000p re.googlegroups.com...
Would someone explain why this declaration is illegal: class Sample<T>
where T : Stream, class
Nov 3 '08 #4

P: n/a
Also, restriction by value/reference type has to be the first
constraint. And restriction of new has to be the last.

In this case you will get the error saying that it should be the first
constraint (similar message). If you change it to

class Sample<T>
where T : class,Stream

then my previous comment applies.

puzzlecracker wrote:
Would someone explain why this declaration is illegal: class Sample<T>
where T : Stream, class
Nov 3 '08 #5

P: n/a
On Mon, 03 Nov 2008 10:54:57 -0800, puzzlecracker <ir*********@gmail.com>
wrote:
Would someone explain why this declaration is illegal: class Sample<T>
where T : Stream, class
Well, what does the error message say?

Here's a hint: what kind of type is "Stream"? Is there _any_ type you
could use with the "class" constraint that would either not be redundant
or contradictory?
Nov 3 '08 #6

P: n/a
new()
has to be the last constraint!

for multiple generic type you need to have the where clause for each
generic type. Like this

class Sample<T, Uwhere T: Stream where U:IDisposable
puzzlecracker wrote:
On Nov 3, 1:54 pm, puzzlecracker <ironsel2...@gmail.comwrote:
>Would someone explain why this declaration is illegal: class Sample<T>
where T : Stream, class

They are taken from C# In depth book
And a few more that are also illegal, and I don't understand why
(compiler is less than helpful).

class Sample<Twhere T : Stream, class

class Sample<Twhere T : new(), Stream

class Sample<T,Uwhere T : struct where U : class, T

class Sample<T,Uwhere T : Stream, U : IDisposable
Nov 3 '08 #7

P: n/a
On Nov 3, 2:05*pm, Ashutosh Bhawasinka <discuss...@ashutosh.inwrote:
You can restrict the generic implementation by either a base type or
value/reference type. Not both.

Stream is already a class. So, T will be a reference type (class) if you
restrict T to be a Stream. So, basically you are trying to say class 2
times.

puzzlecracker wrote:
Would someone explain why this declaration is illegal: class Sample<T>
where T : Stream, class
that implies that struct, value types, cannot inherit from Reference
type... argh
Nov 3 '08 #8

P: n/a
On Mon, 03 Nov 2008 11:17:05 -0800, puzzlecracker <ir*********@gmail.com>
wrote:
that implies that struct, value types, cannot inherit from Reference
type... argh
Well, sort of. Value types can and do inherit reference types. For
example, enumeration types inherit Enum, and all value types inherit
Object.

But yes...no matter what specific type you call out in the constraint,
adding "class" to the constraint will either be redundant (if that type is
a reference type) or contradictory (if that type is a value type).

Pete
Nov 3 '08 #9

P: n/a
Yes, value types (struct) can't inherit from either struct or class.
However they can (only) implement interfaces.

puzzlecracker wrote:
On Nov 3, 2:05 pm, Ashutosh Bhawasinka <discuss...@ashutosh.inwrote:
>You can restrict the generic implementation by either a base type or
value/reference type. Not both.

Stream is already a class. So, T will be a reference type (class) if you
restrict T to be a Stream. So, basically you are trying to say class 2
times.

puzzlecracker wrote:
>>Would someone explain why this declaration is illegal: class Sample<T>
where T : Stream, class

that implies that struct, value types, cannot inherit from Reference
type... argh
Nov 3 '08 #10

P: n/a
Value type does *inherit *implicitly. But no *explicit *inheritance is
allowed.

Peter Duniho wrote:
On Mon, 03 Nov 2008 11:17:05 -0800, puzzlecracker
<ir*********@gmail.comwrote:
>that implies that struct, value types, cannot inherit from Reference
type... argh

Well, sort of. Value types can and do inherit reference types. For
example, enumeration types inherit Enum, and all value types inherit
Object.

But yes...no matter what specific type you call out in the constraint,
adding "class" to the constraint will either be redundant (if that
type is a reference type) or contradictory (if that type is a value
type).

Pete
Nov 3 '08 #11

P: n/a
On Nov 3, 7:02*pm, puzzlecracker <ironsel2...@gmail.comwrote:
Would someone explain why this declaration is illegal: class Sample<T>
where T : Stream, class

They are taken from C# *In depth book
And a few more that are also illegal, and I don't understand why
(compiler is less than helpful).
<snip>

There have been lots of good answers - but I'd just like to point out
one problem with this section of the book. There is a genuine
technical error - see http://csharpindepth.com/ViewNote.aspx?NoteID=121
for details. Basically the constraint "class Sample<Twhere T :
class, Stream, new()" is listed as valid, but it isn't.

Jon
Nov 4 '08 #12

P: n/a
On Nov 4, 4:29*am, "Jon Skeet [C# MVP]" <sk...@pobox.comwrote:
There have been lots of good answers - but I'd just like to point out
one problem with this section of the book. There is a genuine
technical error - seehttp://csharpindepth.com/ViewNote.aspx?NoteID=121
for details. Basically the constraint "class Sample<Twhere T :
class, Stream, new()" is listed as valid, but it isn't.

Jon
Why would it be invalid? All it's saying that the close type of
instance is required to be class, inherit from Stream and have
parameterless constructor.

Thanks
Nov 4 '08 #13

P: n/a
You are only allows one primary constraint; both ": class" and ":
Stream" are classed as primary constraints. If you think about it, this
is logical: Stream is a class, so if T : Stream, T *must* be a class.

Marc
Nov 4 '08 #14

P: n/a
On Nov 4, 1:53*pm, puzzlecracker <ironsel2...@gmail.comwrote:
There have been lots of good answers - but I'd just like to point out
one problem with this section of the book. There is a genuine
technical error - see http://csharpindepth.com/ViewNote.aspx?NoteID=121
for details. Basically the constraint "class Sample<Twhere T :
class, Stream, new()" is listed as valid, but it isn't.

*Why would it be invalid? *All it's saying that the close type of
instance is required to be class, inherit from Stream and have
parameterless constructor.
Did you follow the link? I thought the note was pretty clear...

Jon
Nov 4 '08 #15

P: n/a
On Nov 4, 9:56*am, Marc Gravell <marc.grav...@gmail.comwrote:
You are only allows one primary constraint; both ": class" and ":
Stream" are classed as primary constraints. If you think about it, this
is logical: Stream is a class, so if T : Stream, T *must* be a class.

Marc
That implies that value type cannot inherit from reference types?
Nov 4 '08 #16

P: n/a
That implies that value type cannot inherit from reference types?

That is correct. They can't; well, unless you count the implicit :
ValueType, but that is quite the exception. Valid options are:

* : class (any refernce-type including interfaces and excluding delegates)
* : struct (and value-type excluding Nullable<T>)
* : SomeClass (any SomeClass subclass, or SomeClass itself; SomeClass
cannot be sealed)

Marc
Nov 4 '08 #17

P: n/a

"puzzlecracker" <ir*********@gmail.comwrote in message
news:33**********************************@b31g2000 prb.googlegroups.com...
On Nov 4, 4:29 am, "Jon Skeet [C# MVP]" <sk...@pobox.comwrote:
There have been lots of good answers - but I'd just like to point out
one problem with this section of the book. There is a genuine
technical error - seehttp://csharpindepth.com/ViewNote.aspx?NoteID=121
for details. Basically the constraint "class Sample<Twhere T :
class, Stream, new()" is listed as valid, but it isn't.

Jon
>>>>>>>
Why would it be invalid? All it's saying that the close type of
instance is required to be class, inherit from Stream and have
parameterless constructor.
>>>>>>>
where T: class states this about T; "Can be any class", it _doesn't_ state
"Can't be a struct" or "must at least be a class".
where T: Stream states this about T; "Must be a Stream".

Thus where T: class, Stream states this about T;
"Can be any class" and "Must be a Stream". Clearly this is contradition,
since not all classes are Streams.

--
Anthony Jones - MVP ASP/ASP.NET

Nov 4 '08 #18

P: n/a
On Nov 4, 9:06*am, "Anthony Jones" <AnthonyWJo...@yadayadayada.com>
wrote:
"puzzlecracker" <ironsel2...@gmail.comwrote in message

news:33**********************************@b31g2000 prb.googlegroups.com...
On Nov 4, 4:29 am, "Jon Skeet [C# MVP]" <sk...@pobox.comwrote:There have been lots of good answers - but I'd just like to point out
one problem with this section of the book. There is a genuine
technical error - seehttp://csharpindepth.com/ViewNote.aspx?NoteID=121
for details. Basically the constraint "class Sample<Twhere T :
class, Stream, new()" is listed as valid, but it isn't.
Jon

*Why would it be invalid? *All it's saying that the close type of
instance is required to be class, inherit from Stream and have
parameterless constructor.

where T: class states this about T; "Can be any class", it _doesn't_ state
"Can't be a struct" or "must at least be a class".
where T: Stream states this about T; "Must be a Stream".

Thus where T: class, Stream states this about T;
"Can be any class" and "Must be a Stream". *Clearly this is contradition,
since not all classes are Streams.

--
Anthony Jones - MVP ASP/ASP.NET
Then it is a totally different beast. In this case, Stream indicates
that it has to be class Stream, and not any class. Then why

where T:class, ISomeInterface is allowed?
Nov 4 '08 #19

P: n/a
On Nov 4, 2:06*pm, "Anthony Jones" <AnthonyWJo...@yadayadayada.com>
wrote:

<snip>
where T: class states this about T; "Can be any class", it _doesn't_ state
"Can't be a struct" or "must at least be a class".
where T: Stream states this about T; "Must be a Stream".

Thus where T: class, Stream states this about T;
"Can be any class" and "Must be a Stream". *Clearly this is contradition,
since not all classes are Streams.
No, that's not the reason - you can, for instance, do T : class, new()
which means "can be any class which has a parameterless constructor".

The problem isn't that they're contradictory, but that there's
redundancy - if you know that T derives from Stream, you already know
that T is a class.

Jon
Nov 4 '08 #20

P: n/a
On Nov 4, 2:06*pm, "Anthony Jones" <AnthonyWJo...@yadayadayada.com>
wrote:

<snip>
where T: class states this about T; "Can be any class", it _doesn't_ state
"Can't be a struct" or "must at least be a class".
where T: Stream states this about T; "Must be a Stream".

Thus where T: class, Stream states this about T;
"Can be any class" and "Must be a Stream". *Clearly this is contradition,
since not all classes are Streams.
No, that's not the reason - you can, for instance, do T : class, new()
which means "can be any class which has a parameterless constructor".

The problem isn't that they're contradictory, but that there's
redundancy - if you know that T derives from Stream, you already know
that T is a class.

Jon
Nov 4 '08 #21

P: n/a

"Jon Skeet [C# MVP]" <sk***@pobox.comwrote in message
news:c4**********************************@t18g2000 prt.googlegroups.com...
On Nov 4, 2:06 pm, "Anthony Jones" <AnthonyWJo...@yadayadayada.com>
wrote:

<snip>
where T: class states this about T; "Can be any class", it _doesn't_ state
"Can't be a struct" or "must at least be a class".
where T: Stream states this about T; "Must be a Stream".

Thus where T: class, Stream states this about T;
"Can be any class" and "Must be a Stream". Clearly this is contradition,
since not all classes are Streams.
No, that's not the reason - you can, for instance, do T : class, new()
which means "can be any class which has a parameterless constructor".

The problem isn't that they're contradictory, but that there's
redundancy - if you know that T derives from Stream, you already know
that T is a class.

Jon
>>>>>>>
I get that but the OP seemed to be struggling with redunancy as an argument.
By expressing it as a contradiction (which it is) it might be better
absorbed. Redunancy isn't intinsically an error, for example, there are
many places where the keyword private would be redundant yet its not error
to use in those places, hence simply because something is redundant doesn't
mean its in error. So I can understand the "because its redundant" doesn't
quite cut it.

I think Marc has it with the "there can be only one" primary constraint
explanation.

--
Anthony Jones - MVP ASP/ASP.NET

Nov 4 '08 #22

P: n/a


"puzzlecracker" <ir*********@gmail.comwrote in message
news:dd**********************************@a3g2000p rm.googlegroups.com...
On Nov 4, 9:06 am, "Anthony Jones" <AnthonyWJo...@yadayadayada.com>
wrote:
"puzzlecracker" <ironsel2...@gmail.comwrote in message

news:33**********************************@b31g2000 prb.googlegroups.com...
On Nov 4, 4:29 am, "Jon Skeet [C# MVP]" <sk...@pobox.comwrote:There
have been lots of good answers - but I'd just like to point out
one problem with this section of the book. There is a genuine
technical error - seehttp://csharpindepth.com/ViewNote.aspx?NoteID=121
for details. Basically the constraint "class Sample<Twhere T :
class, Stream, new()" is listed as valid, but it isn't.
Jon

Why would it be invalid? All it's saying that the close type of
instance is required to be class, inherit from Stream and have
parameterless constructor.

where T: class states this about T; "Can be any class", it _doesn't_ state
"Can't be a struct" or "must at least be a class".
where T: Stream states this about T; "Must be a Stream".

Thus where T: class, Stream states this about T;
"Can be any class" and "Must be a Stream". Clearly this is contradition,
since not all classes are Streams.
Then it is a totally different beast. In this case, Stream indicates
that it has to be class Stream, and not any class. Then why

where T:class, ISomeInterface is allowed?
>>>>>>>>>>>>>>>>
Agreed. The contradiction argument doesn't hold just thought it might help.
The truth is wot Marc says, the list of contraints can contain only one
primary constraint class, struct or a specific type. The reason this
restriction is there is that anything else would be pointless due to it
being redundant.

--
Anthony Jones - MVP ASP/ASP.NET

Nov 4 '08 #23

P: n/a
On Nov 4, 12:18*pm, "Jon Skeet [C# MVP]" <sk...@pobox.comwrote:
On Nov 4, 2:06*pm, "Anthony Jones" <AnthonyWJo...@yadayadayada.com>
wrote:

<snip>
where T: class states this about T; "Can be any class", it _doesn't_ state
"Can't be a struct" or "must at least be a class".
where T: Stream states this about T; "Must be a Stream".
Thus where T: class, Stream states this about T;
"Can be any class" and "Must be a Stream". *Clearly this is contradition,
since not all classes are Streams.

No, that's not the reason - you can, for instance, do T : class, new()
which means "can be any class which has a parameterless constructor".

The problem isn't that they're contradictory, but that there's
redundancy - if you know that T derives from Stream, you already know
that T is a class.

Jon
How is it a redundancy if struct can also inherit from class
(reference type)?
Nov 4 '08 #24

P: n/a
On Tue, 04 Nov 2008 10:36:38 -0800, puzzlecracker <ir*********@gmail.com>
wrote:
How is it a redundancy if struct can also inherit from class
(reference type)?
The problem here is that you're drawing an inference from the constraint
rules that isn't true. In particular, you are saying that the constraint
rules imply that value types can't inherit from reference types. But they
make no such implication.

What the constraint rules _do_ imply is that any given type must _itself_
be a reference type ("class") or a value type ("struct"). This is
consistent with the rules of C#, and doesn't in any way preclude the
inheritance of reference types by value types.

Pete
Nov 4 '08 #25

P: n/a
puzzlecracker <ir*********@gmail.comwrote:
How is it a redundancy if struct can also inherit from class
(reference type)?
Structs can only inherit from classes in a very, very limited set of
circumstances - when that class is Object, Enum or ValueType basically.

You can't derive a struct from Stream, for example.

--
Jon Skeet - <sk***@pobox.com>
Web site: http://www.pobox.com/~skeet
Blog: http://www.msmvps.com/jon.skeet
C# in Depth: http://csharpindepth.com
Nov 4 '08 #26

P: n/a
Anthony Jones <An***********@yadayadayada.comwrote:
I get that but the OP seemed to be struggling with redunancy as an argument.
By expressing it as a contradiction (which it is) it might be better
absorbed.
But it's the wrong reason - and if you start applying that elsewhere,
you'll get a skewed view. For instance, by your logic this should be
invalid too:

void Foo<T>() where T : class, IDisposable

That's perfectly valid though.

": class" simply doesn't mean "T can be any reference type" - it means
"T *must* be a reference type; other constraints may be applied too".
Redunancy isn't intinsically an error, for example, there are
many places where the keyword private would be redundant yet its not error
to use in those places, hence simply because something is redundant doesn't
mean its in error. So I can understand the "because its redundant" doesn't
quite cut it.
That's why it's forbidden in this case, however. There are plenty of
other places where redundancy is forbidden too - for instance,
declaring a const as "static".
I think Marc has it with the "there can be only one" primary constraint
explanation.
It's much the same thing, IMO. Note how Marc's answer referred to the
redundancy...

--
Jon Skeet - <sk***@pobox.com>
Web site: http://www.pobox.com/~skeet
Blog: http://www.msmvps.com/jon.skeet
C# in Depth: http://csharpindepth.com
Nov 4 '08 #27

P: n/a
I have read the article about constraints on type parameters at

http://msdn.microsoft.com/en-us/libr...(printer).aspx

I still don't quite understand it. We implement generic classes
because we want it to be applicable to any objects.

But if a generic list class which constrains that it only takes
objects of type Employee like so:

public class GenericList<Twhere T : Employee
{
private Node next;
private T data;
[snip]
}

, then why don't we simply create a specific list class like below
since it restricts to Employee type only?

public class EmployeeList
{
private Node next;
private Employee data;
[snip]
}

Any hint please? Thanks.
Nov 5 '08 #28

P: n/a

"Author" <gn********@gmail.comwrote in message
news:f0**********************************@r15g2000 prh.googlegroups.com...
>I have read the article about constraints on type parameters at

http://msdn.microsoft.com/en-us/libr...(printer).aspx

I still don't quite understand it. We implement generic classes
because we want it to be applicable to any objects.

But if a generic list class which constrains that it only takes
objects of type Employee like so:

public class GenericList<Twhere T : Employee
{
private Node next;
private T data;
[snip]
}

, then why don't we simply create a specific list class like below
since it restricts to Employee type only?

public class EmployeeList
{
private Node next;
private Employee data;
[snip]
}

Any hint please? Thanks.
Prior to the arrival of Generics in C# 2 this is exactly what you had to do.
However this is a real pain when you have some general functionality (which
is where we get the term Generic) that you have to repeat over and over
again.

You would have to create an CompanyList and an AddressList and a ProjectList
and a ... all containing pretty much identical code except for a few
methods and properties would return a specific type and/or a few parameters
would have the same specific type.

You could of course just use an existing list class that simply used object
but then you're left with casts being peppered all over the place and the
compiler couldn't give you the compile time type checking you'd like.
Alternatively you create all these various (what were known as strongly
typed) class that delegated to an internal common implementation.

What Generics gives us the ability to write the functionality once and
re-use it for various types whilst maintaining "stongly typed"
implementations that gives compile time type checking.

These:-

List<Company>
List<Employee>
List<Address>
List<Project>

automatically cause the compiler to generate new types based on a Generic
type save a whole bunch of duplicate coding.

--
Anthony Jones - MVP ASP/ASP.NET

Nov 5 '08 #29

P: n/a
On Nov 5, 2:27*pm, "Anthony Jones" <AnthonyWJo...@yadayadayada.com>
wrote:
"Author" <gnewsgr...@gmail.comwrote in message

news:f0**********************************@r15g2000 prh.googlegroups.com...
I have read the article about constraints on type parameters at
http://msdn.microsoft.com/en-us/libr...(printer).aspx
I still don't quite understand it. *We implement generic classes
because we want it to be applicable to any objects.
But if a generic list class which constrains that it only takes
objects of type Employee like so:
public class GenericList<Twhere T : Employee
{
* * * *private Node next;
* * * *private T data;
* * * [snip]
}
, then why don't we simply create a specific list class like below
since it restricts to Employee type only?
public class EmployeeList
{
* * * *private Node next;
* * * *private Employee data;
* * * [snip]
}
Any hint please? *Thanks.

Prior to the arrival of Generics in C# 2 this is exactly what you had to do.
However this is a real pain when you have some general functionality (which
is where we get the term Generic) that you have to repeat over and over
again.

You would have to create an CompanyList and an AddressList and a ProjectList
and a ... *all containing pretty much identical code except for a few
methods and properties would return a specific type and/or a few parameters
would have the same specific type.

You could of course just use an existing list class that simply used object
but then you're left with casts being peppered all over the place and the
compiler couldn't give you the compile time type checking you'd like.
Alternatively you create all these various (what were known as strongly
typed) class that delegated to an internal common implementation.

What Generics gives us the ability to write the functionality once and
re-use it for various types whilst maintaining "stongly typed"
implementations that gives compile time type checking.

These:-

List<Company>
List<Employee>
List<Address>
List<Project>

automatically cause the compiler to generate new types based on a Generic
type save a whole bunch of duplicate coding.

--
Anthony Jones - MVP ASP/ASP.NET
Thank you, but I guess my question was skipped. :-) I understand
Generics and I have been programming with generics for a while.

My question was this:

If we will implement a generic class GenericList and constrains it to
the type Employee as shown below,

public class GenericList<Twhere T : Employee
{
private Node next;
private T data;
[snip]
}

then, why don't we simply implement a concrete EmployeeList like below
instead of implementing a generic class and restrict it to type
Employee (the latter is essentially pretending to be generic)?

public class EmployeeList
{
private Node next;
private Employee data;
[snip]
}

Do you see what I was asking now? Thanks.
Nov 5 '08 #30

P: n/a
On Wed, 05 Nov 2008 12:29:02 -0800, Author <gn********@gmail.comwrote:
[...]
public class GenericList<Twhere T : Employee
{
private Node next;
private T data;
[snip]
}

then, why don't we simply implement a concrete EmployeeList like below
instead of implementing a generic class and restrict it to type
Employee (the latter is essentially pretending to be generic)?

public class EmployeeList
{
private Node next;
private Employee data;
[snip]
}

Do you see what I was asking now? Thanks.
The short answer:

GenericList<AccountingEmployeeaccountants = ...;
GenericList<ProductionEmployeeworkers = ...;

workers = accountants; // FAILS! The compiler won't let you do this

As opposed to:

EmployeeList accountants = ...;
EmployeeList workers = ...;

workers = accountants; // Oops! Now we're got a bunch of CPAs handling
dangerous machines

In fact, there are actually a number of other advantages that a
constrained generic offers over a non-generic that just uses a base class,
but they all generally lead to the same thing: a much-enhanced degree of
compile-time type safety that you simply wouldn't get without generic
classes. In particular, it's not just about sharing funcionality; it's
about sharing functionality without losing type information.

Pete
Nov 6 '08 #31

P: n/a
On Nov 5, 7:36*pm, "Peter Duniho" <NpOeStPe...@nnowslpianmk.com>
wrote:
On Wed, 05 Nov 2008 12:29:02 -0800, Author <gnewsgr...@gmail.comwrote:
[...]
public class GenericList<Twhere T : Employee
{
* * * *private Node next;
* * * *private T data;
* * * [snip]
}
then, why don't we simply implement a concrete EmployeeList like below
instead of implementing a generic class and restrict it to type
Employee (the latter is essentially pretending to be generic)?
public class EmployeeList
{
* * * * private Node next;
* * * * private Employee data;
* * * *[snip]
}
Do you see what I was asking now? *Thanks.

The short answer:

* * *GenericList<AccountingEmployeeaccountants = ...;
* * *GenericList<ProductionEmployeeworkers = ...;

* * *workers = accountants; *// FAILS! *The compiler won't let you do this

As opposed to:

* * *EmployeeList accountants = ...;
* * *EmployeeList workers = ...;

* * *workers = accountants; // Oops! Now we're got a bunch of CPAs handling *
dangerous machines

In fact, there are actually a number of other advantages that a *
constrained generic offers over a non-generic that just uses a base class, *
but they all generally lead to the same thing: a much-enhanced degree of *
compile-time type safety that you simply wouldn't get without generic *
classes. *In particular, it's not just about sharing funcionality; it's*
about sharing functionality without losing type information.

Pete
I just gave it a shot by having AccountingEmployee and
ProductionEmployee inheriting from Employee. And like you said, the
compiler will not allow the following assignment:

accountingEmployeeList = productionEmployeeList;

So, I think it is fair to say that when a generic class has a single
constraint (e.g. Employee), the advantage of this constrained generic
class will only show up when it is used for inherited classes of
Employee.

Otherwise, if the generic class has a single constraint (e.g.
Employee) and nothing inherits from Employee (or if Employee cannot be
inherited), then

class GenericList<Twhere T: Employee

is completely equivalent to the non-generic EmployeeList as I have
shown.

Is this correct? Thanks.
Nov 6 '08 #32

P: n/a
On Thu, 06 Nov 2008 08:10:58 -0800, Author <gn********@gmail.comwrote:
[...]
Otherwise, if the generic class has a single constraint (e.g.
Employee) and nothing inherits from Employee (or if Employee cannot be
inherited), then

class GenericList<Twhere T: Employee

is completely equivalent to the non-generic EmployeeList as I have
shown.

Is this correct? Thanks.
Yes. If there is only ever going to be one class that can fulfill the
constraint, then you can only ever create a single version of the generic
type, and so it would be impossible to ever reuse the code in the generic
class with any other type, obviating any benefit from the generic class.

Of course, that scenario simply isn't relevant to what generics are useful
for. So I'm not sure that the observation is helpful. But it is a true
observation. :)

Pete
Nov 6 '08 #33

P: n/a
On Nov 6, 2:49*pm, "Peter Duniho" <NpOeStPe...@nnowslpianmk.com>
wrote:
On Thu, 06 Nov 2008 08:10:58 -0800, Author <gnewsgr...@gmail.comwrote:
[...]
Otherwise, if the generic class has a single constraint (e.g.
Employee) and nothing inherits from Employee (or if Employee cannot be
inherited), then
class GenericList<Twhere T: Employee
is completely equivalent to the non-generic EmployeeList as I have
shown.
Is this correct? *Thanks.

Yes. *If there is only ever going to be one class that can fulfill the *
constraint, then you can only ever create a single version of the generic*
type, and so it would be impossible to ever reuse the code in the generic*
class with any other type, obviating any benefit from the generic class.

Of course, that scenario simply isn't relevant to what generics are useful *
for. *So I'm not sure that the observation is helpful. *But it is a true *
observation. *:)

Pete
The observation is helpful for people who haven't thought about
inheritance (like me, I believe many other junior OO programmers as
well) and thus are confused by the MSDN example at

http://msdn.microsoft.com/en-us/library/d5x73970.aspx

where GenerList<Thas a single constraint.

Of course, I am sure there are many junior OO programmers out there
who simply take the example for granted and never seriously think why
a single constraint for a generic class. :-)
Nov 6 '08 #34

P: n/a
On Thu, 06 Nov 2008 12:11:06 -0800, Author <gn********@gmail.comwrote:
The observation is helpful for people who haven't thought about
inheritance (like me, I believe many other junior OO programmers as
well) and thus are confused by the MSDN example at

http://msdn.microsoft.com/en-us/library/d5x73970.aspx

where GenerList<Thas a single constraint.
Hmmm...well, that is an unfortunate code sample, I'd agree. It does
actually say this:

The constraint enables the generic class to use the Employee.Name
property because all items of type T are guaranteed to be either
an Employee object or an object that inherits from Employee.

That is, they do explicitly call out the possibility of an inherited
class. But I agree, the example would be more useful if it actually
_showed_ a constraint using a base class, and then using the generic class
with derived types.
Of course, I am sure there are many junior OO programmers out there
who simply take the example for granted and never seriously think why
a single constraint for a generic class. :-)
Well, I still think the example isn't useful. But at least now I know
where it came from. :)

You might want to consider submitting some feedback suggesting to
Microsoft that they make the example more useful and clear by adding some
derived types to the code for use with the generic.

Pete
Nov 7 '08 #35

P: n/a
On Nov 6, 8:03*pm, "Peter Duniho" <NpOeStPe...@nnowslpianmk.com>
wrote:
On Thu, 06 Nov 2008 12:11:06 -0800, Author <gnewsgr...@gmail.comwrote:
The observation is helpful for people who haven't thought about
inheritance (like me, I believe many other junior OO programmers as
well) and thus are confused by the MSDN example at
http://msdn.microsoft.com/en-us/library/d5x73970.aspx
where GenerList<Thas a single constraint.

Hmmm...well, that is an unfortunate code sample, I'd agree. *It does *
actually say this:

* * *The constraint enables the generic class to use the Employee.Name
* * *property because all items of type T are guaranteed to be either
* * *an Employee object or an object that inherits from Employee.

That is, they do explicitly call out the possibility of an inherited *
class. *But I agree, the example would be more useful if it actually *
_showed_ a constraint using a base class, and then using the generic class *
with derived types.
Hah, I am not a careful reader. I didn't notice that sentence.
Of course, I am sure there are many junior OO programmers out there
who simply take the example for granted and never seriously think why
a single constraint for a generic class. :-)

Well, I still think the example isn't useful. *But at least now I know *
where it came from. *:)

You might want to consider submitting some feedback suggesting to *
Microsoft that they make the example more useful and clear by adding some*
derived types to the code for use with the generic.
Do they listen? I once wrote to them and asked if they could please
make the MSDN banner collapsible (with a + and - button click) because
my monitor is only 17", the main content area shows up very small on
my monitor and thus hard to read. (see the screen shot below) It is
not always convenient to do full-screen or to shrink the left frame
which has the navigation menus. I didn't expect them to listen
anyway.

http://gnewsgroup.googlepages.com/as...full;init:.PNG
Nov 7 '08 #36

P: n/a
On Fri, 07 Nov 2008 07:33:36 -0800, Author <gn********@gmail.comwrote:
[...]
>You might want to consider submitting some feedback suggesting to *
Microsoft that they make the example more useful and clear by adding
some *
derived types to the code for use with the generic.

Do they listen?
I would expect them to be more responsive with respect to content issues
than presentation issues, especially when comparing content issues for a
specific topic to presentation issues that affect the entire web site.

But in any case, I can guarantee that if no one points out the problem,
the chances of them fixing it are _much_ less than if someone does. :)

Pete
Nov 7 '08 #37

This discussion thread is closed

Replies have been disabled for this discussion.