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

  • Thread starter Thread starter puzzlecracker
  • Start date Start date
P

puzzlecracker

Would someone explain why this declaration is illegal: class Sample<T>
where T : Stream, class
 
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<T> where T : Stream, class

class Sample<T> where T : new(), Stream

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

class Sample<T,U> where T : Stream, U : IDisposable
 
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.
 
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?
 
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.
 
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, U> where T: Stream where U:IDisposable
 
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.

that implies that struct, value types, cannot inherit from Reference
type... argh
 
Yes, value types (struct) can't inherit from either struct or class.
However they can (only) implement interfaces.
 
Value type does *inherit *implicitly. But no *explicit *inheritance is
allowed.
 
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<T> where T :
class, Stream, new()" is listed as valid, but it isn't.

Jon
 
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<T> where 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
 
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<T> where 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.
 
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
 
 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
 
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?
 
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
 
 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?
 
On Nov 4, 2:06 pm, "Anthony Jones" <[email protected]>
wrote:

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
 
On Nov 4, 2:06 pm, "Anthony Jones" <[email protected]>
wrote:

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
 
On Nov 4, 2:06 pm, "Anthony Jones" <[email protected]>
wrote:

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.
 
Back
Top