Elegant way to implement repetition block in C# [duplicate] - c#

This question already has answers here:
Is there an elegant way to repeat an action?
(11 answers)
Closed 5 years ago.
A common pattern in coding is to use a iteration variable to do something certain number of times. In many cases, the iteration variable is only used as loop termination condition but adds several lines of code for the purpose.
Example,
int counter=100;
while ( counter > 0)
{
//Do something
counter--;
}
Does the .NET framework provide a way to define a coding block (Do something in example) and then execute it a given number of times, thereby removing the condition checking and decrementing statements above. This is to reduce the number of visible statements.
Edit: I am looking for way to reduce the number of codes, not make the underlying call efficient.

whats wrong with
for (int counter = 0; counter < limit; counter++)
{
//Do something
}
its an instantly recognizable idiom

There is no option in .NET Framework to do something N times without keeping track of number of times you already did something.
But you can write your own extension which will hide all this stuff. E.g.
public static void Times(this int count, Action action)
{
if (count < 0)
throw new ArgumentException(nameof(count));
for(int i = 0; i < count; i++)
action();
}
Usage:
100.Times(() => Console.WriteLine("hello"))
Note that if you'll extract the code which you want to repeat into method which matches Action signature, then the code above becomes cleaner:
100.Times(DoSomething);

You could use the Enumerable.Repeat to do the trick, not sure if it's really what you thought of elegance
Edit :
Little example how you can generate 100 different random values with this method. With a little adaptation it could suit your need
var ran = new Random();
var results = Enumerable.Repeat<Func<int>>(ran.Next, 100)
.Select(f => f())
.ToArray();
Edit:
I thought you could make it on your own, but some people need clarifications :
Enumerable.Repeat(100, () =>
{
// Do what you want
});
Source (for more details):
http://geekswithblogs.net/BlackRabbitCoder/archive/2012/05/03/c.net-little-wonders-the-enumerable.repeat-static-method.aspx

Related

How to step into Linq.FindAll query to determine cause of failure using a breakpoint [duplicate]

This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 8 months ago.
I want to use the FindAll method in C# in like this:
List<Card> cards = new List<Card>();
cards.AddRange(testCaseCards);
Console.WriteLine(cards.Count);
List<List<Card>> cardsSuits = new List<List<Card>>();
List<Card> tempList = new List<Card>();
for (int i = 0; i < 4; ++i)
{
Console.WriteLine(cards[i].Suit);
tempList = cards.FindAll(card => card.Suit == (Suit)i);
cardsSuits.Add(tempList);
}
When I initialize my code with testCaseCards containing 9 cards, everything works just fine up until the FindAll query. The value of cards.Count is 9 and cards[i].Suit returns the respective suits.
But when FindAll executes it throws an exception that "card was null" and I'm looking for a way to step into the FindAll as it goes through the cards and set a breakpoint to examine values and determine the exact cause of failure. I looked at this answer which mentions Linq in passing but doesn't provide any real guidance about debugging a null exception while the Linq query is running.
Also, if you notice any other problems in my code please point them out.
One way to debug the FindAll (or any Linq) is by creating a Predicate method. For example:
private static bool isSuit(Card card, Suit suit)
{
if (card == null)
{
// Set a break point here. When the null card comes in
// (as it surely will) you can answer 'why' for yourself.
System.Diagnostics.Debug.Assert(false, "Expecting a non-null card");
return false; // But at least it won't crash now.
}
else
{
return card.Suit == suit;
}
}
Now you will be able to step into this method by changing your FindAll statement to call the predicate instead:
tempList = cards.FindAll(card => isSuit(card, suit));
In addition there is another potential problem. You have a loop where i could mean anything.
for (int i = 0; i < 4; ++i)
In fact the first two statements in the loop interpret it in very different ways. The first statement in the loop seems to think that i is the index in the cards collection. You say cards holds 9 cards. Why stop the loop after 4 then?
Console.WriteLine(cards[i].Suit);
On the other hand, the second line tries to cast i to Suit (which has only four values). if i does go past 4, this won't be good. I would strongly encourage you to change your loop to something like this where we know for sure which collection is being iterated:
foreach (Suit suit in Enum.GetValues(typeof(Suit)))
{
Console.Write(suit.ToString());
tempList = cards.FindAll(card => isSuit(card, suit));
cardsSuits.Add(tempList);
Console.WriteLine($" has {tempList.Count} cards.");
}
The test case I ran gets this:

What is the 'ctr' variable in a parallel C# loop? [duplicate]

This question already has answers here:
What does the '=>' syntax in C# mean?
(7 answers)
Closed 1 year ago.
I recently used a Parallel.For loop (see code below) in a small C# program and I'm a little perplexed by the ctr variable. Every example I've seen so far has the name of this variable set to ctr, but I cant seem to find any good resource on what it means or why exactly this name is used.
If anyone knows more about it, I would be happy to hear it!
public static int[] calcArray(int[] arrName, int arrSize, int seed)
{
Parallel.For(0, arrSize, ctr =>
{
arrName[ctr] = AllfunctionsClass.Random(seed);
seed++;
});
return arrName;
}
The current index value.. imagine a normal for loop
for (int ctr=0; ctr < arraySize; ctr++)
{
// ctr is the current value between 0 and arraySize-1
}
The variable name chosen as arbitrary in this case, probably short for counter. IMHO variable names should very rarely be abbrvted and should make it obvious what they represent e.g. arrayPosition or position or maybe index or something like that

Is using a math class method in a loop condition slow?

if i have a for loop for example and and i want to use something like Math.round() to round the number but i only need to round the number one time(i.e the number doesn't change throughout the loop) is it better to store it into a variable and then use the variable to in the condition or does it not matter?
for (int i = 0;i < Math.Round(x);i++)
{
//Some code
}
vs
for (int i = 0,roundedX = Math.Round(X); i<roundedX;i++)
{
//Some code
}
The compiler will evaluate the termination condition on every loop iteration.
The compiler and the JITter might hoist some expression or part of an expression outside the loop if it deems it is invariant, meaning it doesn't change. This, however, is usually only done with simpler expressions.
If the Math.Round(X) expression could've been done without an actual method call then perhaps but in this particular case the rounding will happen on each loop iteration.
As such, if you're at last line defense for performance problems, you might consider moving this out and into a variable:
int goal = (int)Math.Round(X);
for (int i = 0; i < goal; i++)
...
As this will call the Math.Round method only once, you only get the performance hit once.
Note that if X changes as part of the loop, then obviously you want to keep your original code.
I would suggest defining a variable
var roundedX = Math.Round(X);
for (int i = 0; i < roundedX; i++)
{
//Some code
}

is String.Contains() faster than walking through whole array of char in string?

I have a function that is walking through the string looking for pattern and changing parts of it. I could optimize it by inserting
if (!text.Contains(pattern)) return;
But, I am actually walking through the whole string and comparing parts of it with the pattern, so the question is, how String.Contains() actually works? I know there was such a question - How does String.Contains work? but answer is rather unclear. So, if String.Contains() walks through the whole array of chars as well and compare them to pattern I am looking for as well, it wouldn't really make my function faster, but slower.
So, is it a good idea to attempt such an optimizations? And - is it possible for String.Contains() to be even faster than function that just walk through the whole array and compare every single character with some constant one?
Here is the code:
public static char colorchar = (char)3;
public static Client.RichTBox.ContentText color(string text, Client.RichTBox SBAB)
{
if (text.Contains(colorchar.ToString()))
{
int color = 0;
bool closed = false;
int position = 0;
while (text.Length > position)
{
if (text[position] == colorchar)
{
if (closed)
{
text = text.Substring(position, text.Length - position);
Client.RichTBox.ContentText Link = new Client.RichTBox.ContentText(ProtocolIrc.decode_text(text), SBAB, Configuration.CurrentSkin.mrcl[color]);
return Link;
}
if (!closed)
{
if (!int.TryParse(text[position + 1].ToString() + text[position + 2].ToString(), out color))
{
if (!int.TryParse(text[position + 1].ToString(), out color))
{
color = 0;
}
}
if (color > 9)
{
text = text.Remove(position, 3);
}
else
{
text = text.Remove(position, 2);
}
closed = true;
if (color < 16)
{
text = text.Substring(position);
break;
}
}
}
position++;
}
}
return null;
}
Short answer is that your optimization is no optimization at all.
Basically, String.Contains(...) just returns String.IndexOf(..) >= 0
You could improve your alogrithm to:
int position = text.IndexOf(colorchar.ToString()...);
if (-1 < position)
{ /* Do it */ }
Yes.
And doesn't have a bug (ahhm...).
There are better ways of looking for multiple substrings in very long texts, but for most common usages String.Contains (or IndexOf) is the best.
Also IIRC the source of String.Contains is available in the .Net shared sources
Oh, and if you want a performance comparison you can just measure for your exact use-case
Check this similar post How does string.contains work
I think that you will not be able to simply do anything faster than String.Contains, unless you want to use standard CRT function wcsstr, available in msvcrt.dll, which is not so easy
Unless you have profiled your application and determined that the line with String.Contains is a bottle-neck, you should not do any such premature optimizations. It is way more important to keep your code's intention clear.
Ans while there are many ways to implement the methods in the .NET base classes, you should assume the default implementations are optimal enough for most people's use cases. For example, any (future) implementation of .NET might use the x86-specific instructions for string comparisons. That would then always be faster than what you can do in C#.
If you really want to be sure whether your custom string comparison code is faster than String.Contains, you need to measure them both using many iterations, each with a different string. For example using the Stopwatch class to measure the time.
If you now the details which you can use for optimizations (not just simple contains check) sure you can make your method faster than string.Contains, otherwise - not.

Looping through a method without for/foreach/while

Is there a way of calling a method/lines of code multiple times not using a for/foreach/while loop?
For example, if I were to use to for loop:
int numberOfIterations = 6;
for(int i = 0; i < numberOfIterations; i++)
{
DoSomething();
SomeProperty = true;
}
The lines of code I'm calling don't use 'i' and in my opinion the whole loop declaration hides what I'm trying to do. This is the same for a foreach.
I was wondering if there's a looping statement I can use that looks something like:
do(6)
{
DoSomething();
SomeProperty = true;
}
It's really clear that I just want to execute that code 6 times and there's no noise involving index instantiating and adding 1 to some arbitrary variable.
As a learning exercise I have written a static class and method:
Do.Multiple(int iterations, Action action)
Which works but scores very highly on the pretentious scale and I'm sure my peers wouldn't approve.
I'm probably just being picky and a for loop is certainly the most recognisable, but as a learning point I was just wondering if there (cleaner) alternatives. Thanks.
(I've had a look at this thread, but it's not quite the same)
Using IEnumerable without foreach loop
Actually, the for loop does not hide what you're trying to do.
Anyone reading your code is already familiar with standard for loops and will understand instantly what you're doing.
You could score even more highly on the pretension scale by making it an extension method:
public static void Times(this int iterations, Action action)
{
for (int i = 0; i < iterations; i++)
{
action();
}
}
...
6.Times(() => {
DoSomething();
SomeProperty = true;
});
But I would definitely stick with a for loop. It's the idiomatic, well-recognised way of doing it.
Not a loop in sight
private MethodDelegate MultiMethod(MethodDelegate m, int count) {
MethodDelegate a;
if (count > 0) {
a = m;
a += MultiMethod(m, --count);
} else {
a = delegate { };
}
return a;
}
and you get a great syntax for invocation!
MultiMethod(action, 99)();
How about a do....until or if...then
Use a counter inside the loop and have it loop UNTIL the counter reaches 6.
Or an if-then statement with a counter. If your value is 6, break out of the loop.
I'm not a programming guru, but if you have an action that needs to be done a set number of times, there would be a need for a counter somewhere, whether it's a function of your loop or if it has to be created with a counter.

Categories