.NET Forum / .NET Framework / CLR / December 2007
Generics Question
|
|
Thread rating:  |
Scott M. - 23 Nov 2007 17:28 GMT 1. Although I get the relative simplicity of Generics over using interfaces is it true that I *could* do what Generics offers with interfaces?
Mattias Sjögren - 23 Nov 2007 17:46 GMT >1. Although I get the relative simplicity of Generics over using interfaces >is it true that I *could* do what Generics offers with interfaces? No, regular (non-generic) interfaces doesn't provide a way for you to parameterize types.
Mattias
 Signature Mattias Sjögren [C# MVP] mattias @ mvps.org http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com Please reply only to the newsgroup.
Scott M. - 23 Nov 2007 18:32 GMT Why not? If I use a paremeterized constructor that asks for a type that is an interface, wouldn't that work?
>>1. Although I get the relative simplicity of Generics over using >>interfaces [quoted text clipped - 4 lines] > > Mattias Jon Skeet [C# MVP] - 23 Nov 2007 19:13 GMT > Why not? If I use a paremeterized constructor that asks for a type that is > an interface, wouldn't that work? How would you build an equivalent of List<T> using interfaces, such that you get the same kind of compile-time type safety?
 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
Scott M. - 23 Nov 2007 19:28 GMT I don't know Jon, that's why I asked the question.
>> Why not? If I use a paremeterized constructor that asks for a type that >> is >> an interface, wouldn't that work? > > 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 [C# MVP] - 23 Nov 2007 20:01 GMT > I don't know Jon, that's why I asked the question. 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*.
 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
Scott M. - 23 Nov 2007 21:31 GMT 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?
>> I don't know Jon, that's why I asked the question. > [quoted text clipped - 4 lines] > everything that generics offers with interfaces, because interfaces > don't allow you to parameterize types or methods *by types*. Jon Skeet [C# MVP] - 23 Nov 2007 21:38 GMT > 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? 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.
 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
Scott M. - 23 Nov 2007 22:09 GMT 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?
>> 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? [quoted text clipped - 15 lines] > commonly useful (as new code), but most of the time you'll find > yourself *using* generic types rather than creating new ones. Jon Skeet [C# MVP] - 23 Nov 2007 22:36 GMT > I do understand the benefits of Generics: the type safety they birng and the > time that they save. Right. Things that can't be done just by using interfaces.
> My question is more for academic reasons. > [quoted text clipped - 15 lines] > > Now emp is acting like <T> would in a Gerneic type is it not? 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.
 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
Scott M. - 23 Nov 2007 23:27 GMT I think my question is mostly answered from this last reply. See inline...
>> I do understand the benefits of Generics: the type safety they birng and >> the >> time that they save. > > Right. Things that can't be done just by using interfaces. 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.
>> My question is more for academic reasons. >> [quoted text clipped - 20 lines] > I'm sorry, I really don't see the overlap between interfaces and > generics here at all. 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).
> 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). 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.
> 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. 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.
> 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. I appreciate your replies.
-Scott
Jon Skeet [C# MVP] - 24 Nov 2007 00:16 GMT > I think my question is mostly answered from this last reply. See inline...
> >> I do understand the benefits of Generics: the type safety they birng and > >> the [quoted text clipped - 7 lines] > Interfaces. It may be harder and it may require more safety's, but I > believe it can be done. 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.)
> >> Now emp is acting like <T> would in a Gerneic type is it not? > > [quoted text clipped - 6 lines] > present interfaces as a pre-Generics way of solving some problems that > Generics solve (this example being one of them). 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.
> > Yes, you can use emp and it'll be strongly typed. > > However: [quoted text clipped - 6 lines] > constructor as it, no casting required. And no casting would be required to > use it as an IEmployee inside the class either. 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.
> > For instance, you can't expose another member of the class with the > > specific IEmployee implementation used by the constructor, because you [quoted text clipped - 5 lines] > 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. 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".
 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
Scott M. - 24 Nov 2007 02:40 GMT >> What? Any class that implements IEmployee can be passed into the foo >> constructor as it, no casting required. And no casting would be required [quoted text clipped - 6 lines] > of those classes (we've created them ourselves). You only know about > IEmployee. Perhaps, but that was not the scenario I've proposed (see below for more).
> Now: > [quoted text clipped - 26 lines] > and just complicates matters. That's very different from saying that > you "*could* do what Generics offers with interfaces". 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.
Jon Skeet [C# MVP] - 24 Nov 2007 07:45 GMT > > 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 [quoted text clipped - 5 lines] > you only ever be supplying SalariedEmployees, we'd just change my class to > accept SalariedEmployees in its constructor instead of IEmployee. 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.
> 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. 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.
> Show me how I couldn't make a class that takes only Salaried Employees then. You could - but not in a generic way.
> 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. You can't do type parameterization without generics. What you're doing isn't what the rest of the world calls type parameterization.
> I've provided an example (a parameterized constructor). The type itself hasn't been parameterized - you've got a constructor with a parameter, which is a very different thing.
> Now, you are changing the requirements to need to be able to > accept SalariedEmployees The requirements as I understood them were to show you that generics are necessary - that you fake them with generics.
> It does not seem that your statement > that I can't create a parameterized type using Interfaces is accurate. Again, accepting a parameter isn't the same as type parameterization.
> 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. 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.
 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
Scott M. - 24 Nov 2007 15:43 GMT 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.
Jon Skeet [C# MVP] - 24 Nov 2007 17:41 GMT > 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. So why did you ask whether it was possible to achieve everything given by generics just using interfaces?
> 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. 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.
> But, I do think I've got what I was looking for now. Well, I'm glad you think so, but it still sounds to me like you're very confused about what type parameterization really means.
 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
Barry Kelly - 30 Nov 2007 23:46 GMT > 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. 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.
> 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. 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
 Signature http://barrkel.blogspot.com/
Scott M. - 01 Dec 2007 01:46 GMT > 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 [quoted text clipped - 3 lines] > other possible implementations. They're all about static typing. Plain > and simple. 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.
Barry Kelly - 02 Dec 2007 01:56 GMT > My questions have > been about the observable results, not the purpose or under the hood > benefits of generics. I am asking for academic reasons. 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
 Signature http://barrkel.blogspot.com/
Scott M. - 02 Dec 2007 06:41 GMT 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.
>> My questions have >> been about the observable results, not the purpose or under the hood [quoted text clipped - 5 lines] > > -- Barry Ben Voigt [C++ MVP] - 03 Dec 2007 16:21 GMT >> My questions have >> been about the observable results, not the purpose or under the hood [quoted text clipped - 3 lines] > questions are for the "reasons", but not the "purpose" - but the purpose > is the reason! 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.
> -- Barry Barry Kelly - 03 Dec 2007 17:02 GMT > >> My questions have > >> been about the observable results, not the purpose or under the hood [quoted text clipped - 9 lines] > same as the language designers' purpose for providing generics, even if the > words "reasons" and "purpose" be synonyms. 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
 Signature http://barrkel.blogspot.com/
Ben Voigt [C++ MVP] - 04 Dec 2007 18:49 GMT >> >> My questions have >> >> been about the observable results, not the purpose or under the hood [quoted text clipped - 17 lines] > behind the design of generics, not that his reasons for asking were > academic. I can definitely see it that way too.
"I have academic reasons for asking." would have been far clearer.
> -- Barry
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|