Calculating primes until a user-given value
So this is a curious writeup, because primes can be calculated in many, many ways.

That said, there's one huge optimization we can use to cut your search pattern in half, and it starts here:


for (ulong i = 4; i&lt;inputnumber; i++)
{



Fun fact: the only prime even number is 2, so we can actually rewrite this very quickly to remove half of the numbers you need to search:

for (ulong i = 5; i&lt;inputnumber; i += 2)
{


Bam. Cut our search grid in half.

The next thing I would do is remove 2 from the List&lt;ulong&gt; of results, and we'll insert it later, because that will never match any of the values we're searching now:

var primes = new List&lt;ulong&gt;();
primes.Add(3);
...
primes.Insert(0, 2);


That way we get another speed boost, without sacrificing any of the rest of our code. (Are there better ways to do this? Sure.)



Next, we need to talk about some "best practices" and such:

Console.WriteLine("The Range from 0 to " + inputvar + " has " + Convert.ToString(numberofprimes) + " primes.");


This is something we call "string concatenation", basically, string1 + string2. It's frowned upon, and we recommend not doing it. Instead, use a formatted string, in one of two ways:

Console.WriteLine("The Range from 0 to {0} has {1} primes.", inputvar, numberofprimes);
Console.WriteLine($"The Range from 0 to {inputvar} has {numberofprimes} primes.");


Either will work, though the second is only supported in C# 6.0.



Next, there's one more huge optimization to make, and it's at this line:

double result = 0;


You don't realize it, but there's a boatload of casting/conversions here that shouldn't exist. Replace double with ulong and it goes away.

What's happening, is i % prime is a ulong, that is being casted to a double when assigned to result. This is an expensive operation, because the two types are stored in memory in completely different formats. Change the type, and you should get a 50%+ speed boost. (At least, I did.)



Additionally, you don't really need result, you don't use it for anything. So, I recommend removing it, and rewriting the foreach as follows:

for (ulong i = 5; i &lt; inputnumber; i += 2)
{
    isprime = true;
    foreach (ulong prime in primes)
    {
        if (i % prime == 0UL)
        {
            isprime = false;
            break;
        }
    }
    if (isprime == true)
    {
        primes.Add(i);
    }
}


This gives you another speed boost, surprisingly.



Lastly, I recommend initializing the List with a default buffer. This should help avoid "resizing" that happens throughout the lifetime of the program. I used 500000, but as long as you use something reasonable (even 10000 is fine) it will give you a decent performance boost. (1-2%)



Overall, when we're done, the algorithm should look something like:

var primes = new List&lt;ulong&gt;(10000);
primes.Add(3);
bool isprime = false;
for (ulong i = 5; i &lt; inputnumber; i += 2)
{
    isprime = true;
    foreach (ulong prime in primes)
    {
        if (i % prime == 0UL)
        {
            isprime = false;
            break;
        }
    }
    if (isprime == true)
    {
        primes.Add(i);
    }
}
primes.Insert(0, 2);
int numberofprimes = primes.Count;