all groups > dotnet clr > november 2007 >
You're in the

dotnet clr

group:

Generics Question



Generics Question Scott M.
11/23/2007 12:28:44 PM
dotnet clr: 1. Although I get the relative simplicity of Generics over using interfaces
is it true that I *could* do what Generics offers with interfaces?

Re: Generics Question Scott M.
11/23/2007 1:32:13 PM
Why not? If I use a paremeterized constructor that asks for a type that is
an interface, wouldn't that work?


[quoted text, click to view]

Re: Generics Question Scott M.
11/23/2007 2:28:25 PM
I don't know Jon, that's why I asked the question.


[quoted text, click to view]

Re: Generics Question Scott M.
11/23/2007 4:31:57 PM
But that's what I don 't understand. Why can't I create a parameterized
constructor for a class and have its parameter be of an interface type?

Sub New(x As IEmployee)

Then this type would be essentially parameterized, would it not?



[quoted text, click to view]

Re: Generics Question Scott M.
11/23/2007 5:09:24 PM
I do understand the benefits of Generics: the type safety they birng and the
time that they save. My question is more for academic reasons.

If I expan on my last signature....

Class foo

Private emp As IEmployee

Sub New(x As IEmployee)
emp = x
End Sub

Private Sub New

End Sub

End Class

Now emp is acting like <T> would in a Gerneic type is it not? "emp" can be
used by any member of this type and with type-safety. I'm going to get type
safety when someone attempt to instance a "foo" (and passes something other
than an IEmployee) and I'm going to get type-safety (and intellisense) when
"emp" is used throughout the class.

Again, just to be clear, I fully understand how Generics makes this much
simpler and gives me the added benefit of its built-in type safety. But,
I'm wondering *if* I can accomplish the same results by passing Interfaces
with Is there some other benefit I'm missing?



[quoted text, click to view]

Re: Generics Question Scott M.
11/23/2007 6:27:59 PM
I think my question is mostly answered from this last reply. See inline...


[quoted text, click to view]

Again, I ask why? Interfaces may not bring the same level of type safety as
List(of T), but they do provide a type of saftey, in that a contraint is
being put on the input. I just don't buy that "it can't be done" using
Interfaces. It may be harder and it may require more safety's, but I
believe it can be done.

[quoted text, click to view]

I've been reading Professional .NET 2.0 Generics (wrox) and the author does
present interfaces as a pre-Generics way of solving some problems that
Generics solve (this example being one of them).

[quoted text, click to view]

What? Any class that implements IEmployee can be passed into the foo
constructor as it, no casting required. And no casting would be required to
use it as an IEmployee inside the class either.

[quoted text, click to view]

Sure. But if I'm only interested in the IEmployee members, this is not a
problem. My whole premis here is based on the assumption that IEmployee
contains the members I want to use. Rememer: I'm already sold on Generics,
I'm looking for a devil's advocate agument on the need for them.

[quoted text, click to view]

I appreciate your replies.

-Scott

[quoted text, click to view]

Re: Generics Question Mattias Sjögren
11/23/2007 6:46:00 PM

[quoted text, click to view]

No, regular (non-generic) interfaces doesn't provide a way for you to
parameterize types.


Mattias

--
Mattias Sjögren [C# MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Re: Generics Question Jon Skeet [C# MVP]
11/23/2007 7:13:59 PM
[quoted text, click to view]

How would you build an equivalent of List<T> using interfaces, such
that you get the same kind of compile-time type safety?

--
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
Re: Generics Question Jon Skeet [C# MVP]
11/23/2007 8:01:24 PM
[quoted text, click to view]

Well, you asked it in a way that sounded like you were proposing a
solution. What would your parameterized constructor look like?

In short, to answer your original question: no, you couldn't do
everything that generics offers with interfaces, because interfaces
don't allow you to parameterize types or methods *by types*.

--
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
Re: Generics Question Jon Skeet [C# MVP]
11/23/2007 9:38:48 PM
[quoted text, click to view]

No, it wouldn't. It would be taking an IEmployee, but that doesn't make
the rest of the type parameterized *by type*.

Again, look at List<T>. Look at what it gives you in terms of strong
typing. Now try to construct the same sort of thing without generics.
Really, try it - I suspect that's the best way of seeing why generics
are important.

Now in many cases you don't *need* generics - it's very rare for it to
be worth creating your own generic type; generic methods are more
commonly useful (as new code), but most of the time you'll find
yourself *using* generic types rather than creating new ones.

--
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
Re: Generics Question Scott M.
11/23/2007 9:40:04 PM
[quoted text, click to view]

Perhaps, but that was not the scenario I've proposed (see below for more).

[quoted text, click to view]

But Generics doesn't help me here either. In your case of *knowing* that
you only ever be supplying SalariedEmployees, we'd just change my class to
accept SalariedEmployees in its constructor instead of IEmployee. And, with
a Generic:

List(of SalariedEmployees) we'd be able to pass a SalariedEmployee just as
we would with a:

New(x As SalariedEmployee) on my class.

Show me how I couldn't make a class that takes only Salaried Employees then.
I started this (with you) by asking why a parameterized constructor wouldn't
satisfy what Gernerics can when you said that I can't do a parameterized
type without Generics. I've provided an example (a parameterized
constructor). Now, you are changing the requirements to need to be able to
accept SalariedEmployees and I'm countering by saying that I'd change my
constructor parameter to accomodate that requirement. I'd have to change
the type on my Generic Type if you changed its intenal requirements as well,
so we're back to my initial point. It does not seem that your statement
that I can't create a parameterized type using Interfaces is accurate.
Please explain why I'm wrong (you haven't done that). If you simply propose
a new scenario as your proof, then I will counter with a new constructor to
accomodate your new requirement.
[quoted text, click to view]

Re: Generics Question Jon Skeet [C# MVP]
11/23/2007 10:36:41 PM
[quoted text, click to view]

Right. Things that can't be done just by using interfaces.

[quoted text, click to view]

No. It's just acting as an interface implementation.

I'm sorry, I really don't see the overlap between interfaces and
generics here at all. Yes, you can use emp and it'll be strongly typed.
However:

1) It will be boxed if the implementation is a value type
2) You can *only* use it as an IEmployee unless you perform casting at
runtime (losing the safety).

For instance, you can't expose another member of the class with the
specific IEmployee implementation used by the constructor, because you
don't know that at compile-time. Basically, you have no information
other than the fact that it's *some* implementation of IEmployee.

There are plenty of times when that's enough, but that doesn't mean
that generics are either meant to be a replacement for interfaces *or*
that interfaces can do the same things as generics.

--
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
Re: Generics Question Jon Skeet [C# MVP]
11/24/2007 12:16:48 AM
[quoted text, click to view]

You've just said that interfaces don't bring the same level of type
safety as List<T> - so it *can't* be done. You can't do everything with
interfaces that you can do with generics. (Nor can you do everything
with generics that you can do with interfaces.)

[quoted text, click to view]

Generics aren't trying to solve the same problem though, and generics
certainly don't replace interfaces. Either the author is confused, or
you're not understanding him properly.

[quoted text, click to view]

Suppose I (as a client) want to only use your class with
SalariedEmployees. Someone else wants to only use it with
ContractEmployees. You (as the class provider) don't know about either
of those classes (we've created them ourselves). You only know about
IEmployee.

Now:

1) You can't provide a class which assures me at compile time I haven't
mixed and matched usages of SalariedEmployee with ContractEmployee.

2) You can only expose employees to me as IEmployee, despite the fact
that I *know* I'm only ever going to give you SalariedEmployees.

Generics fixes both of these.

[quoted text, click to view]

Then don't just present a situation where you *don't* need them. It's
like suggesting that reference types are unnecessary because in one
particular situation you only need integers.

If you're only interested in IEmployee members, and you don't need to
allow the client to impose extra type safety (e.g. always using a
particular implementation of IEmployee) then generics has no benefit,
and just complicates matters. That's very different from saying that
you "*could* do what Generics offers with interfaces".

--
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
Re: Generics Question Jon Skeet [C# MVP]
11/24/2007 7:45:33 AM
[quoted text, click to view]

No, you've missed the point. You've supplied the class to me already.
It can't be changed. Alternatively, we want to use the same code in two
places, for different types.

[quoted text, click to view]

Yes, but in order to do that you need to know about SalariedEmployee
first, and you'd have to have one class for each type that you wanted
to treat in that way.

[quoted text, click to view]

You could - but not in a generic way.

[quoted text, click to view]

You can't do type parameterization without generics. What you're doing
isn't what the rest of the world calls type parameterization.

[quoted text, click to view]

The type itself hasn't been parameterized - you've got a constructor
with a parameter, which is a very different thing.

[quoted text, click to view]

The requirements as I understood them were to show you that generics
are necessary - that you fake them with generics.

[quoted text, click to view]

Again, accepting a parameter isn't the same as type parameterization.

[quoted text, click to view]

Create a class which can restrict (at compile-time of the *user* of the
class) what can be passed to either the constructor or other methods,
when you (as the class author) don't know which type I (as the user)
wish to restrict the use by.

In other words, you're going to write the class, and *then* I will
decide which type I wish to restrict the use to - just as I can create
a List<string> which will *only* store strings.

--
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
Re: Generics Question Scott M.
11/24/2007 10:43:13 AM
Jon,

I do get your point and I haven't misunderstood anyting (you or the author
of the book I'm reading). You've misunderstood what I'm asking. I'm not
talking about the semantics of building a reusable class that doesn't need
to know at its creation what will be passed into it later. I get that, but
I'm talking about the mechanics of the the parameter passing and what that
parameter in the constructor does. Your getting hung up on this.

The fact is that (per my first reply to you) I *can* pass a parameter to my
type that (mechanically) acts as <T> would in a parameterized type.

But, I do think I've got what I was looking for now.

Thanks.
Re: Generics Question Jon Skeet [C# MVP]
11/24/2007 5:41:11 PM
[quoted text, click to view]

So why did you ask whether it was possible to achieve everything given
by generics just using interfaces?

[quoted text, click to view]

No, it *doesn't*. It doesn't act at all like T would in a parameterized
type. A constructor parameter doesn't parameterize the type, it acts as
a parameter for a specific instance of the type. That's a big
difference.

[quoted text, click to view]

Well, I'm glad you think so, but it still sounds to me like you're very
confused about what type parameterization really means.

--
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
Re: Generics Question Scott M.
11/30/2007 8:46:41 PM

[quoted text, click to view]

I understand (and have understood that) Barry. I do not misunderstand the
concepts. Perhaps I wasn't clear enough in my question. My questions have
been about the observable results, not the purpose or under the hood
benefits of generics. I am asking for academic reasons.

Re: Generics Question Barry Kelly
11/30/2007 11:46:37 PM
[quoted text, click to view]

Scott, I think I understand what you've misunderstood. I think you
somehow got the idea, once upon a time, that generics enable a certain
class of solutions, where such solutions are semantic in nature (e.g.
write a class that can "maintain a list of stuff", etc.). Now, you've
stumbled across interfaces, and it's dawned on you that you can use
interfaces to do the same semantic thing ("maintain a list of stuff" so
long as "stuff" implements the interface) and you're seeing a semantic
equivalence here.

The thing is, the feature that generics brings to the table, isn't this
capability to implement certain semantics (and thus being equivalent or
a subset of interfaces); it's rather that it enables such semantics *in*
*a* *statically-typed* *way* - and this is the very feature that
interfaces / polymorphism *doesn't* provide. They only work with dynamic
typing.

[quoted text, click to view]

A parameterized type is a type constructor. By passing it type
arguments, you're creating what effectively is a *new* type, statically
checked at compile time. You *cannot* create such a new type by passing
an interface reference to a constructor.

You know the features that generics bring to the table, but you're
thinking in terms of end results, i.e. observable program actions, and
you can see that interfaces (or ever System.Object) can do the same
thing. But the trouble is, that isn't what generics are about - they
aren't about enabling new kinds of end results, to the exclusion of
other possible implementations. They're all about static typing. Plain
and simple.

-- Barry

--
Re: Generics Question Scott M.
12/2/2007 1:41:29 AM
I don't believe I ever stated what you are saying. I asked why I can't get
the same result with Interfaces that I can with Generics. I should have
been clearer that when I say "result" I meant "end result", not operational
results.


[quoted text, click to view]
Re: Generics Question Barry Kelly
12/2/2007 1:56:35 AM
[quoted text, click to view]

Then there's a direct logical contradiction in your position: your
questions are for the "reasons", but not the "purpose" - but the purpose
is the reason!

-- Barry

--
Re: Generics Question Ben Voigt [C++ MVP]
12/3/2007 10:21:35 AM

[quoted text, click to view]

You're drawing equivalence where there is none:

His reasons (asserted to be academic) for studying generics need not be the
same as the language designers' purpose for providing generics, even if the
words "reasons" and "purpose" be synonyms.

[quoted text, click to view]

Re: Generics Question Barry Kelly
12/3/2007 5:02:22 PM
[quoted text, click to view]

No, I misread his last sentence: when he said he was asking for academic
reasons, I interpreted that as him asking for the academic reasons
behind the design of generics, not that his reasons for asking were
academic.

-- Barry

--
Re: Generics Question Ben Voigt [C++ MVP]
12/4/2007 12:49:18 PM

[quoted text, click to view]

I can definitely see it that way too.

"I have academic reasons for asking." would have been far clearer.

[quoted text, click to view]

AddThis Social Bookmark Button