tag:blogger.com,1999:blog-3573606178901893990.post5312314216485953757..comments2024-01-28T01:30:51.917-08:00Comments on The Monkey's Grinder: Who's Afraid of Generic Variance?Unknownnoreply@blogger.comBlogger7125tag:blogger.com,1999:blog-3573606178901893990.post-68301525675407164632009-04-11T12:01:00.000-07:002009-04-11T12:01:00.000-07:00Scott:Suppose I'm creating an enumerable type, say...Scott:<BR/><BR/>Suppose I'm creating an enumerable type, say for example to expose a collection of content.<BR/><BR/>Suppose further that the content is long-lived, potentially longer-lived than client code making use of it.<BR/><BR/>Again, suppose that sometime down the line the content is augmented with metadata about the author.<BR/><BR/>We therefore have the situation of:<BR/><BR/>class Content<BR/>{<BR/> string Name;<BR/>}<BR/><BR/>class Author<BR/>{<BR/> string Name;<BR/>}<BR/><BR/>class ContentCollection: IEnumerable[Content], IEnumerable[Author]<BR/><BR/>New code would be advised to explicitly cast to the appropriate IE[T], but suppose there is older client code not under your control that just wants to cycle through the contents of the collection, but only knows about IEnumerable[object].Keith J. Farmerhttp://www.thuban.orgnoreply@blogger.comtag:blogger.com,1999:blog-3573606178901893990.post-69136656545577318252009-04-10T02:13:00.000-07:002009-04-10T02:13:00.000-07:00Well done article. Thanks.I'd go for restricti...Well done article. Thanks.<BR/><BR/>I'd go for restrictive. After all, C# was designed as a language of the verbose kind (state your intent), and generics/variance are really not much more than syntactic sugar to avoid redundant specification of intent. However, once things can become ambiguous, the goal has clearly been overshot.<BR/><BR/>I'd say it is perfectly alright if C# 3 code breaks under C# 4 because of the new ambiguities. I wager, less than 1% of code would be affected and easily fixed. I can see the rise of an generic adapter type for this specific purpose. Also, generators (yield) seem to me to largely obsolete the use of explicit IEnumerables<Tit>..<Tat> and other stereotypical examples.Unknownhttps://www.blogger.com/profile/12918356527984032595noreply@blogger.comtag:blogger.com,1999:blog-3573606178901893990.post-86874033835337502442009-04-10T00:41:00.000-07:002009-04-10T00:41:00.000-07:00We should forbid the creation of a method if it ma...We should forbid the creation of a method if it makes the type ambiguous, either because two methods in the same class are ambiguous, or because a parent class already contains a method that will make the new method ambiguous.<BR/><BR/>I don't think that this limitation would be annoying. It will only make the code clearer to non-expert. The current spec will only make C# unreadable.Laurent Debackerhttps://www.blogger.com/profile/02754216642339658436noreply@blogger.comtag:blogger.com,1999:blog-3573606178901893990.post-12957143278124989962009-04-09T22:02:00.000-07:002009-04-09T22:02:00.000-07:00Keith, could you give us an overview of how you us...Keith, could you give us an overview of how you use potentially ambiguous code and why?Scotthttps://www.blogger.com/profile/13066415518426794033noreply@blogger.comtag:blogger.com,1999:blog-3573606178901893990.post-82104999322582864832009-04-09T20:16:00.000-07:002009-04-09T20:16:00.000-07:00I'd be fine making ambiguities illegal, provided a...I'd be fine making ambiguities illegal, provided a way to disambiguate <I>without changing the essence of the type definition</I> were provided. For example, a marker attribute. Alternatively, order of appearence in the base type lists would be acceptable for me.<BR/><BR/>I happen to have written code that could potentially qualify for the Sophie's Choice scenario, so.. don't break it :)Keith J. Farmerhttp://www.thuban.orgnoreply@blogger.comtag:blogger.com,1999:blog-3573606178901893990.post-80125756890260719932009-04-09T19:39:00.000-07:002009-04-09T19:39:00.000-07:00Yet another potential rule:1. The most derived im...Yet another potential rule:<BR/><BR/>1. The most derived implementation wins, <I>even if it's not an exact match</I>.<BR/><BR/>Thus, in Case 1, Y.I<B> is used to provide I<A>, and in Case 2 class Y is used.<BR/><BR/>When that path ends, we hit:<BR/><BR/>2. If a class implements the same interface multiple times, use the most derived implementation. Thus, for Case 3, I<A> should use the I<C> implementation.<BR/><BR/>The reason for this is to reinforce Good Design -- usually when this happens the I<B> and I<C> methods will need to do the same or similar things, which will usually be to return the most derived type. So run with it.<BR/><BR/>Alas, this dies with Case 4 (Sophies choice) -- neither is most derived. This should be an error, at least until someone presents an actual in-use design example that does this (at which point I can scream "WHY?!?!?!").<BR/><BR/>If Case 4 can't be an error, I'd argue that you should go with the first valid implementation in the inheritance list (I<B> in this case), <I>not</I> the first alphabetical choice, as this allows the class designer to change the preferred ordering if necessary.<BR/><BR/>I'd still prefer the error here.Jonathan Pryorhttps://www.blogger.com/profile/14099006045921906356noreply@blogger.comtag:blogger.com,1999:blog-3573606178901893990.post-27918428746097176432009-04-09T18:45:00.000-07:002009-04-09T18:45:00.000-07:00That was really funny :)That was really funny :)Rodrigo B. de Oliveirahttps://www.blogger.com/profile/11376961210011805178noreply@blogger.com