From: Mel Weaver on 16 Jun 2010 14:45 Try this, just a reminder c# is case sensitive? using System.Collections.Generic; public static class EnumerableExtensions { private static readonly Random random = new Random(); public static IEnumerable<T> selectrandomitem<T>(this IEnumerable<T> source, int total) { if (source == null) yield break; T[] data = source.ToArray(); if (total < 0 || total > data.Length) { throw new ArgumentException(); } for (int i = 0; i < total; i++) { int index = random.Next(data.Length - i); yield return data[index]; data[index] = data[data.Length - i - 1]; } } } "Rich P" <rpng123(a)aol.com> wrote in message news:OXm3jsXDLHA.4400(a)TK2MSFTNGP05.phx.gbl... > Thank you for your reply. This did fix one of the complaints from > VS2008, but he is still complaining about one other guy. Here is the > sample class that I copied from another post with the recommended fix of > adding <T> to ...class EnumerableExtensions : > > public static class EnumerableExtensions<T> > { > private static readonly Random random = new Random(); > > //--VS2008 is complaining about "selecttrandomitem<t>" > > public static ienumerable<t> selectrandomitem<t>(this ienumerable<t> > source, int total) > { > if (source == null) yield break; > > T[] data = source.ToArray(); > > if (total < 0 || total > data.Length) > { > throw new ArgumentException(); > } > > for (int i = 0; i < total; i++) > { > int index = random.Next(data.Length - i); > > yield return data[index]; > > data[index] = data[data.Length - i - 1]; > } > } > } > > Here is the error message for "selecttrandomitem<t>" > > "The body of > 'MySampleApp.EnumerableExtensions<T>.selectrandomitem<t>(ienumerable<t>, > int)' cannot be an iterator block because 'ienumerable<t>' is not an > iterator interface type" > > This sample class is great for learning Generics in C#. May I ask how I > could fix this error based on the context of the sample above? > > Thanks > > Rich > > *** Sent via Developersdex http://www.developersdex.com ***
From: Rich P on 16 Jun 2010 15:05 OK. Now I have this class -- which VS is not complaining about. How to I use a class like this? Could someone share a sample usage? public static class enumerableextensions<t> { private static readonly Random random = new Random(); public static IEnumerable<t> selectrandomitem<t>(this IEnumerable<t> source, int total) { if (source == null) yield break; t[] data = source.ToArray(); if (total < 0 || total > data.Length) { throw new ArgumentException(); } for (int i = 0; i < total; i++) { int index = random.Next(data.Length - i); yield return data[index]; data[index] = data[data.Length - i - 1]; } } } In the post I copied this from -- VS complains about the following usage and I don't see a connection to the class above: static void Main(string[] args) { var data = Enumerable.Range(0, 21); //--VS complains here about "SelectRandomItem" foreach (var item in data.SelectRandomItem(10)) { Console.WriteLine(item); } } I tried changing the casing of "SelectRandomItem", VS still complain, and still I don't see the connection to the class above. The post was about picking 10 numbers randomly from a list of numbers. I just copied this post to study usage of Generics. Rich *** Sent via Developersdex http://www.developersdex.com ***
From: kndg on 16 Jun 2010 21:43 On 6/17/2010 3:05 AM, Rich P wrote: > OK. Now I have this class -- which VS is not complaining about. How to > I use a class like this? Could someone share a sample usage? > > public static class enumerableextensions<t> > { > private static readonly Random random = new Random(); > > public static IEnumerable<t> selectrandomitem<t>(this IEnumerable<t> > source, int total) > { > if (source == null) yield break; > > t[] data = source.ToArray(); > > if (total< 0 || total> data.Length) > { > throw new ArgumentException(); > } > > for (int i = 0; i< total; i++) > { > int index = random.Next(data.Length - i); > > yield return data[index]; > > data[index] = data[data.Length - i - 1]; > } > } > } > > In the post I copied this from -- VS complains about the following usage > and I don't see a connection to the class above: > > static void Main(string[] args) > { > var data = Enumerable.Range(0, 21); > > //--VS complains here about "SelectRandomItem" > foreach (var item in data.SelectRandomItem(10)) > { > Console.WriteLine(item); > } > } > > I tried changing the casing of "SelectRandomItem", VS still complain, > and still I don't see the connection to the class above. The post was > about picking 10 numbers randomly from a list of numbers. I just copied > this post to study usage of Generics. > > > Rich > > *** Sent via Developersdex http://www.developersdex.com *** Hi Rich, I glad that you benefit something from my code. Anyway, as for the comments, if you copy my code exactly as it appear, it should compile fine. - SelectRandomItem is an extension method and it can only be declared on a *non-generic* static class. You had mistakenly make the class generic by adding <t> on the class definition. That's the source of error. - It is a well known practice to use upper-case letter 'T' as a placeholder for the generic type. Otherwise, it will upset your collegues. - You need to work up on proper casing of names. As for the usage, if you follow my example carefully, it will print 10 random numbers in the range of 0 to 20. Another usage is for example suppose you would like to calculate the sum of three dices thrown on the table, static void Main(string[] args) { var dice = Enumerable.Range(1, 6); var threeDices = new List<int>(dice); // first dice threeDices.AddRange(dice); // second dice threeDices.AddRange(dice); // third dice int sumOfThreeDices = threeDices.SelectRandomItem(3).Sum(); Console.WriteLine("Sum of three dice = {0}", sumOfThreeDices); } Regards.
From: Rich P on 17 Jun 2010 11:36 > SelectRandomItem is an extension method and it can only be declared on a *non-generic* static class. You had mistakenly make the class generic by adding <t> on the class definition. That's the source of error. < Thank you for your reply. I still get an error if I copy your class like this: public static class EnumerableExtensions { private static readonly Random random = new Random(); //--VS complains here about selectrandomitem public static ienumerable<t> selectrandomitem<t>(this ienumerable<t> source, int total) { if (source == null) yield break; //--VS complains about T[] T[] data = source.ToArray(); if (total < 0 || total > data.Length) { throw new ArgumentException(); } for (int i = 0; i < total; i++) { int index = random.Next(data.Length - i); //--and VS complains about data[index] yield return data[index]; data[index] = data[data.Length - i - 1]; } } } Here are the error messages I am getting with this class (VS2008) --error1 The body of 'ConsoleApplication1.EnumerableExtensions.selectrandomitem<t>(ienumerabl e<t>, int)' cannot be an iterator block because 'ienumerable<t>' is not an iterator interface type --error2 The type or namespace name 'T' could not be found (are you missing a using directive or an assembly reference?) --error3 Cannot implicitly convert type 'T' to 'object' What should I do to eliminate these errors? Also, not sure if this is of any significance, but I also see that a lot of code sampels have * list<something> x = new list<something>() * on my workstation I don't have a * list *. I have to use uppercase * List *. Is my VS2008 different? I am pretty sure I have all the latest patches for it and service packs (version 3.5 SP1). Thanks, Rich *** Sent via Developersdex http://www.developersdex.com ***
From: kndg on 17 Jun 2010 22:11 On 6/17/2010 11:36 PM, Rich P wrote: >> > SelectRandomItem is an extension method and it can only be declared on a > *non-generic* static class. You had mistakenly make the class generic by > adding<t> on the class definition. That's the source of error. > < > > Thank you for your reply. I still get an error if I copy your class > like this: > > public static class EnumerableExtensions > { > private static readonly Random random = new Random(); > > //--VS complains here about selectrandomitem > public static ienumerable<t> selectrandomitem<t>(this ienumerable<t> > source, int total) > { > if (source == null) yield break; > > //--VS complains about T[] > T[] data = source.ToArray(); > > if (total< 0 || total> data.Length) > { > throw new ArgumentException(); > } > > for (int i = 0; i< total; i++) > { > int index = random.Next(data.Length - i); > //--and VS complains about data[index] > yield return data[index]; > data[index] = data[data.Length - i - 1]; > } > } > } > As I said previously, If you had copy the code exactly as it appear, it should compile fine. You had mistakenly changed the casing for IEnumerable<T> and SelectRandomItem<T> and that cause the compiler to complaint. > Here are the error messages I am getting with this class (VS2008) > > --error1 > The body of > 'ConsoleApplication1.EnumerableExtensions.selectrandomitem<t>(ienumerabl > e<t>, int)' cannot be an iterator block because 'ienumerable<t>' is not > an iterator interface type > As others has said, C# is *case-sensitive*. There is no ienumerable<t> in the framework, only IEnumerable<T> which is defined in System.Collections.Generic namespace. Since I had use 'yield break' and 'yield return' statement in the method block, the return type of the SelectRandomItem method must be of type IEnumerable<T>. > --error2 > The type or namespace name 'T' could not be found (are you missing a > using directive or an assembly reference?) > I had made the SelectRandomItem method generic by adding <T> at the name of methods. You had mistakenly changed the casing from uppercase <T> to lowercase <t>. Generic type declaration have to be consistent with the usage inside the method. If you use lowercase 't' on the method definition, you must also use the same lowercase 't' inside the method body. > --error3 > Cannot implicitly convert type 'T' to 'object' > If you resolve the error2 above, this error should go away. > What should I do to eliminate these errors? > Well, read the code carefully and work up on the proper casing. > Also, not sure if this is of any significance, but I also see that a lot > of code sampels have > > * list<something> x = new list<something>() * > > on my workstation I don't have a * list *. I have to use uppercase * > List *. Is my VS2008 different? I am pretty sure I have all the latest > patches for it and service packs (version 3.5 SP1). > Care to share where do you get that code sample? Maybe a typing error or maybe the author of that code did defined a new type named list<T>? Without the original code, I cannot say for sure but as far as .NET is concerned, all classes name in the framework starts with the uppercase letter. In order to aid your understanding of my code, below are the features that I had used and the links to MSDN website for the details 1. Generics http://msdn.microsoft.com/en-us/library/512aeb7t%28VS.90%29.aspx 2. Iterators http://msdn.microsoft.com/en-us/library/dscyy5s0%28VS.90%29.aspx 3. Extension Methods http://msdn.microsoft.com/en-us/library/bb383977%28VS.90%29.aspx Regards.
First
|
Prev
|
Next
|
Last
Pages: 1 2 3 Prev: sql problem Next: CurrentPrincipal for Thread seems to give wrong result |