How to populate/instantiate a C# array with a single value?

C#ArraysDefault Value

C# Problem Overview


I know that instantiated arrays of value types in C# are automatically populated with the default value of the type (e.g. false for bool, 0 for int, etc.).

Is there a way to auto-populate an array with a seed value that's not the default? Either on creation or a built-in method afterwards (like Java's Arrays.fill())? Say I wanted an boolean array that was true by default, instead of false. Is there a built-in way to do this, or do you just have to iterate through the array with a for loop?

 // Example pseudo-code:
 bool[] abValues = new[1000000];
 Array.Populate(abValues, true);

 // Currently how I'm handling this:
 bool[] abValues = new[1000000];
 for (int i = 0; i < 1000000; i++)
 {
     abValues[i] = true;
 }

Having to iterate through the array and "reset" each value to true seems ineffecient. Is there anyway around this? Maybe by flipping all values?

After typing this question out and thinking about it, I'm guessing that the default values are simply a result of how C# handles the memory allocation of these objects behind the scenes, so I imagine it's probably not possible to do this. But I'd still like to know for sure!

C# Solutions


Solution 1 - C#

Enumerable.Repeat(true, 1000000).ToArray();

Solution 2 - C#

Don't know of a framework method but you could write a quick helper to do it for you.

public static void Populate<T>(this T[] arr, T value ) {
  for ( int i = 0; i < arr.Length;i++ ) {
    arr[i] = value;
  }
}

Solution 3 - C#

Create a new array with a thousand true values:

var items = Enumerable.Repeat<bool>(true, 1000).ToArray();  // Or ToList(), etc.

Similarly, you can generate integer sequences:

var items = Enumerable.Range(0, 1000).ToArray();  // 0..999

Solution 4 - C#

You can use Array.Fill in .NET Core 2.0+ and .NET Standard 2.1+.

Solution 5 - C#

For large arrays or arrays that will be variable sized you should probably use:

Enumerable.Repeat(true, 1000000).ToArray();

For small array you can use the collection initialization syntax in C# 3:

bool[] vals = new bool[]{ false, false, false, false, false, false, false };

The benefit of the collection initialization syntax, is that you don't have to use the same value in each slot and you can use expressions or functions to initialize a slot. Also, I think you avoid the cost of initializing the array slot to the default value. So, for example:

bool[] vals = new bool[]{ false, true, false, !(a ||b) && c, SomeBoolMethod() };

Solution 6 - C#

If your array is so large you should use BitArray. It uses 1 bit for every bool instead of a byte (like in an array of bools) also you can set the all the bits to true with bit operators. Or just initialize on true. If you only need to do it once, it will only cost more though.

System.Collections.BitArray falses = new System.Collections.BitArray(100000, false);
System.Collections.BitArray trues = new System.Collections.BitArray(100000, true);

// Now both contain only true values.
falses.And(trues);

Solution 7 - C#

unfortunately I don't think there is a direct way, however I think you can write an extension method for the array class to do this

class Program
{
    static void Main(string[] args)
    {
        int[] arr = new int[1000];
        arr.Init(10);
        Array.ForEach(arr, Console.WriteLine);
    }
}

public static class ArrayExtensions
{
    public static void Init<T>(this T[] array, T defaultVaue)
    {
        if (array == null)
            return;
        for (int i = 0; i < array.Length; i++)
        {
            array[i] = defaultVaue;
        }
    }
}

Solution 8 - C#

Well after a little more googling and reading I found this:

bool[] bPrimes = new bool[1000000];
bPrimes = Array.ConvertAll<bool, bool>(bPrimes, b=> b=true);

Which is certainly closer to what I'm looking for. But I'm not sure if that's better than iterating through the original array in a for-loop and just changing the values. After a quick test in fact, it appears slower by about a factor of 5. So not really a good solution then!

Solution 9 - C#

The code below combines simple iteration for small copies and Array.Copy for large copies

    public static void Populate<T>( T[] array, int startIndex, int count, T value ) {
        if ( array == null ) {
            throw new ArgumentNullException( "array" );
        }
        if ( (uint)startIndex >= array.Length ) {
            throw new ArgumentOutOfRangeException( "startIndex", "" );
        }
        if ( count < 0 || ( (uint)( startIndex + count ) > array.Length ) ) {
            throw new ArgumentOutOfRangeException( "count", "" );
        }
        const int Gap = 16;
        int i = startIndex;

        if ( count <= Gap * 2 ) {
            while ( count > 0 ) {
                array[ i ] = value;
                count--;
                i++;
            }
            return;
        }
        int aval = Gap;
        count -= Gap;

        do {
            array[ i ] = value;
            i++;
            --aval;
        } while ( aval > 0 );

        aval = Gap;
        while ( true ) {
            Array.Copy( array, startIndex, array, i, aval );
            i += aval;
            count -= aval;
            aval *= 2;
            if ( count <= aval ) {
                Array.Copy( array, startIndex, array, i, count );
                break;
            }
        }
    }

The benchmarks for different array length using an int[] array are :

         2 Iterate:     1981 Populate:     2845
         4 Iterate:     2678 Populate:     3915
         8 Iterate:     4026 Populate:     6592
        16 Iterate:     6825 Populate:    10269
        32 Iterate:    16766 Populate:    18786
        64 Iterate:    27120 Populate:    35187
       128 Iterate:    49769 Populate:    53133
       256 Iterate:   100099 Populate:    71709
       512 Iterate:   184722 Populate:   107933
      1024 Iterate:   363727 Populate:   126389
      2048 Iterate:   710963 Populate:   220152
      4096 Iterate:  1419732 Populate:   291860
      8192 Iterate:  2854372 Populate:   685834
     16384 Iterate:  5703108 Populate:  1444185
     32768 Iterate: 11396999 Populate:  3210109

The first columns is the array size, followed by the time of copying using a simple iteration ( @JaredPared implementation ). The time of this method is after that. These are the benchmarks using an array of a struct of four integers

         2 Iterate:     2473 Populate:     4589
         4 Iterate:     3966 Populate:     6081
         8 Iterate:     7326 Populate:     9050
        16 Iterate:    14606 Populate:    16114
        32 Iterate:    29170 Populate:    31473
        64 Iterate:    57117 Populate:    52079
       128 Iterate:   112927 Populate:    75503
       256 Iterate:   226767 Populate:   133276
       512 Iterate:   447424 Populate:   165912
      1024 Iterate:   890158 Populate:   367087
      2048 Iterate:  1786918 Populate:   492909
      4096 Iterate:  3570919 Populate:  1623861
      8192 Iterate:  7136554 Populate:  2857678
     16384 Iterate: 14258354 Populate:  6437759
     32768 Iterate: 28351852 Populate: 12843259

Solution 10 - C#

What about a parallel implementation

public static void InitializeArray<T>(T[] array, T value)
{
	var cores = Environment.ProcessorCount;

	ArraySegment<T>[] segments = new ArraySegment<T>[cores];

	var step = array.Length / cores;
	for (int i = 0; i < cores; i++)
	{
		segments[i] = new ArraySegment<T>(array, i * step, step);
	}
	var remaining = array.Length % cores;
	if (remaining != 0)
	{
		var lastIndex = segments.Length - 1;
		segments[lastIndex] = new ArraySegment<T>(array, lastIndex * step, array.Length - (lastIndex * step));
	}

	var initializers = new Task[cores];
	for (int i = 0; i < cores; i++)
	{
		var index = i;
		var t = new Task(() =>
		{
			var s = segments[index];
			for (int j = 0; j < s.Count; j++)
			{
				array[j + s.Offset] = value;
			}
		});
		initializers[i] = t;
		t.Start();
	}

	Task.WaitAll(initializers);
}

When only initializing an array the power of this code can't be seen but I think you should definitely forget about the "pure" for.

Solution 11 - C#

Or... you could simply use inverted logic. Let false mean true and vice versa.

Code sample

// bool[] isVisible = Enumerable.Repeat(true, 1000000).ToArray();
bool[] isHidden = new bool[1000000]; // Crazy-fast initialization!

// if (isVisible.All(v => v))
if (isHidden.All(v => !v))
{
    // Do stuff!
}

Solution 12 - C#

Many of the answers presented here boil down to a loop that initializes the array one element at a time, which does not take advantage of CPU instructions designed to operate on a block of memory at once.

.Net Standard 2.1 (in preview as of this writing) provides Array.Fill(), which lends itself to a high-performance implementation in the runtime library (though as of now, .NET Core doesn't seem to leverage that possibility).

For those on earlier platforms, the following extension method outperforms a trivial loop by a substantial margin when the array size is significant. I created it when my solution for an online code challenge was around 20% over the allocated time budget. It reduced the runtime by around 70%. In this case, the array fill was performed inside another loop. BLOCK_SIZE was set by gut feeling rather than experiment. Some optimizations are possible (e.g. copying all bytes already set to the desired value rather than a fixed-size block).

internal const int BLOCK_SIZE = 256;
public static void Fill<T>(this T[] array, T value)
{
	if (array.Length < 2 * BLOCK_SIZE)
	{
		for (int i = 0; i < array.Length; i++) array[i] = value;
	}
	else
	{
		int fullBlocks = array.Length / BLOCK_SIZE;
		// Initialize first block
		for (int j = 0; j < BLOCK_SIZE; j++) array[j] = value;
		// Copy successive full blocks
		for (int blk = 1; blk < fullBlocks; blk++)
		{
			Array.Copy(array, 0, array, blk * BLOCK_SIZE, BLOCK_SIZE);
		}

		for (int rem = fullBlocks * BLOCK_SIZE; rem < array.Length; rem++)
		{
			array[rem] = value;
		}
	}
}

Solution 13 - C#

If you are on .NET Core, .NET Standard >= 2.1, or depend on the System.Memory package, you can also use the Span<T>.Fill() method:

var valueToFill = 165;
var data = new int[100];

data.AsSpan().Fill(valueToFill);

// print array content
for (int i = 0; i < data.Length; i++)
{
	Console.WriteLine(data[i]);
}

https://dotnetfiddle.net/UsJ9bu

Solution 14 - C#

Just a benchmark:

BenchmarkDotNet=v0.12.1, OS=Windows 10.0.18363.997 (1909/November2018Update/19H2)
Intel Core i7-6700HQ CPU 2.60GHz (Skylake), 1 CPU, 8 logical and 4 physical cores
.NET Core SDK=3.1.302
  [Host]        : .NET Core 3.1.6 (CoreCLR 4.700.20.26901, CoreFX 4.700.20.31603), X64 RyuJIT
  .NET Core 3.1 : .NET Core 3.1.6 (CoreCLR 4.700.20.26901, CoreFX 4.700.20.31603), X64 RyuJIT

Job=.NET Core 3.1  Runtime=.NET Core 3.1

|           Method |     Mean |     Error |    StdDev |
|----------------- |---------:|----------:|----------:|
| EnumerableRepeat | 2.311 us | 0.0228 us | 0.0213 us |
|  NewArrayForEach | 2.007 us | 0.0392 us | 0.0348 us |
|        ArrayFill | 2.426 us | 0.0103 us | 0.0092 us |
    [SimpleJob(BenchmarkDotNet.Jobs.RuntimeMoniker.NetCoreApp31)]
    public class InitializeArrayBenchmark {
        const int ArrayLength = 1600;

        [Benchmark]
        public double[] EnumerableRepeat() {
            return Enumerable.Repeat(double.PositiveInfinity, ArrayLength).ToArray();
        }

        [Benchmark]
        public double[] NewArrayForEach() {
            var array = new double[ArrayLength];

            for (int i = 0; i < array.Length; i++) {
                array[i] = double.PositiveInfinity;
            }

            return array;
        }

        [Benchmark]
        public double[] ArrayFill() {
            var array = new double[ArrayLength];
            Array.Fill(array, double.PositiveInfinity);

            return array;
        }
    }

Solution 15 - C#

.NET Core 2.0 and later supports Array.Fill() method.

Here is a sample code.

var arr = new int[10];
int defaultValue = 2;
Array.Fill(arr,defaultValue);

It also has an overload method for range of indices to be filled. More details can be found here.

Solution 16 - C#

this also works...but might be unnecessary

 bool[] abValues = new bool[1000];
 abValues = abValues.Select( n => n = true ).ToArray<bool>();

Solution 17 - C#

There is no way to set all elements in an array as a single operation, UNLESS, that value is the element types default value.

Eg, if it is an array of integers you can set them all to zero with a single operation, like so: Array.Clear(...)

Solution 18 - C#

Here's another version for us Framework users abandoned by Microsoft. It is 4 times as fast as Array.Clear and faster than Panos Theof's solution and Eric J's and Petar Petrov's parallel one - up to two times as fast for large arrays.

First I want to present you the function's ancestor, because that makes it easier to understand the code. Performance-wise this is pretty much on par with Panos Theof's code, and for some things that may already be enough:

public static void Fill<T> (T[] array, int count, T value, int threshold = 32)
{
	if (threshold <= 0)
		throw new ArgumentException("threshold");

	int current_size = 0, keep_looping_up_to = Math.Min(count, threshold);

	while (current_size < keep_looping_up_to)
		array[current_size++] = value;

	for (int at_least_half = (count + 1) >> 1; current_size < at_least_half; current_size <<= 1)
		Array.Copy(array, 0, array, current_size, current_size);

	Array.Copy(array, 0, array, current_size, count - current_size);
}

As you can see, this is based on repeated doubling of the already-initialised part. This is simple and efficient, but it runs afoul of modern memory architectures. Hence was born a version that uses doubling only to create a cache-friendly seed block, which is then blasted iteratively over the target area:

const int ARRAY_COPY_THRESHOLD = 32;  // 16 ... 64 work equally well for all tested constellations
const int L1_CACHE_SIZE = 1 << 15;

public static void Fill<T> (T[] array, int count, T value, int element_size)
{
	int current_size = 0, keep_looping_up_to = Math.Min(count, ARRAY_COPY_THRESHOLD);

	while (current_size < keep_looping_up_to)
		array[current_size++] = value;

	int block_size = L1_CACHE_SIZE / element_size / 2;
	int keep_doubling_up_to = Math.Min(block_size, count >> 1);

	for ( ; current_size < keep_doubling_up_to; current_size <<= 1)
		Array.Copy(array, 0, array, current_size, current_size);

	for (int enough = count - block_size; current_size < enough; current_size += block_size)
		Array.Copy(array, 0, array, current_size, block_size);

	Array.Copy(array, 0, array, current_size, count - current_size);
}

Note: the earlier code needed (count + 1) >> 1 as limit for the doubling loop to ensure that the final copy operation has enough fodder to cover all that is left. This would not be the case for odd counts if count >> 1 were to be used instead. For the current version this is of no significance since the linear copy loop will pick up any slack.

The size of an array cell must be passed as a parameter because - the mind boggles - generics aren't allowed to use sizeof unless they use a constraint (unmanaged) that may or may not become available in the future. Wrong estimates are not a big deal but performance is best if the value is accurate, for the following reasons:

  • Underestimating the element size can lead to block sizes greater than half the L1 cache, hence increasing the likelihood of copy source data getting evicted from L1 and having to be re-fetched from slower cache levels.

  • Overestimating the element size results in under-utilisation of the CPU's L1 cache, meaning the linear block copy loop gets executed more often than it would be with optimal utilisation. Thus, more of the fixed loop/call overhead is incurred than strictly necessary.

Here's a benchmark pitting my code against Array.Clear and the other three solutions mentioned previously. The timings are for filling integer arrays (Int32[]) of the given sizes. In order to reduce variation caused by cache vagaries etc. each test was executed twice, back to back, and the timings were taken for the second execution.

array size   Array.Clear      Eric J.   Panos Theof  Petar Petrov   Darth Gizka
-------------------------------------------------------------------------------
     1000:       0,7 µs        0,2 µs        0,2 µs        6,8 µs       0,2 µs 
    10000:       8,0 µs        1,4 µs        1,2 µs        7,8 µs       0,9 µs 
   100000:      72,4 µs       12,4 µs        8,2 µs       33,6 µs       7,5 µs 
  1000000:     652,9 µs      135,8 µs      101,6 µs      197,7 µs      71,6 µs 
 10000000:    7182,6 µs     4174,9 µs     5193,3 µs     3691,5 µs    1658,1 µs 
100000000:   67142,3 µs    44853,3 µs    51372,5 µs    35195,5 µs   16585,1 µs 

Should the performance of this code not be sufficient then a promising avenue would be parallelising the linear copy loop (with all threads using the same source block), or our good old friend P/Invoke.

Note: clearing and filling of blocks is normally done by runtime routines that branch to highly specialised code using MMX/SSE instructions and whatnot, so in any decent environment one would simply call the respective moral equivalent of std::memset and be assured of professional performance levels. IOW, by rights the library function Array.Clear should leave all our hand-rolled versions in the dust. The fact that it is the other way around shows how far out of whack things really are. Same goes for having to roll one's own Fill<> in the first place, because it is still only in Core and Standard but not in the Framework. .NET has been around for almost twenty years now and we still have to P/Invoke left and right for the most basic stuff or roll our own...

Solution 19 - C#

If you're planning to only set a few of the values in the array, but want to get the (custom) default value most of the time, you could try something like this:

public class SparseArray<T>
{
    private Dictionary<int, T> values = new Dictionary<int, T>();

    private T defaultValue;

    public SparseArray(T defaultValue)
    {
        this.defaultValue = defaultValue;
    }

    public T this [int index]
    {
      set { values[index] = value; }
      get { return values.ContainsKey(index) ? values[index] ? defaultValue; }
    }
}

You'll probably need to implement other interfaces to make it useful, such as those on array itself.

Solution 20 - C#

I realize I'm late to the party but here's an idea. Write a wrapper which has conversion operators to and from the wrapped value so that it can be used as a stand-in for the wrapped type. This was actually inspired by the silly-sounding answer from @l33t.

First (coming from C++) I realized that in C# a default ctor is not called when the elements of an array are constructed. Instead -- even in the presence of a user-defined default constructor! -- all array elements are zero-initialized. That did surprise me.

So a wrapper class which simply provides a default ctor with the desired value would work for arrays in C++ but not in C#. A workaround is to let the wrapper type map 0 to the desired seed value upon conversion. That way zero initialized values appear to be initialized with the seed for all practical purposes:

public struct MyBool
{
    private bool _invertedValue;

    public MyBool(bool b) 
    {   
        _invertedValue = !b;
    }

    public static implicit operator MyBool(bool b)
    {
        return new MyBool(b);
    }

    public static implicit operator bool(MyBool mb)
    {
        return !mb._invertedValue;
    }

}

static void Main(string[] args)
{
        MyBool mb = false; // should expose false.
        Console.Out.WriteLine("false init gives false: " 
                              + !mb);

        MyBool[] fakeBoolArray = new MyBool[100];

        Console.Out.WriteLine("Default array elems are true: " 
                              + fakeBoolArray.All(b => b) );

        fakeBoolArray[21] = false;
        Console.Out.WriteLine("Assigning false worked: " 
                              + !fakeBoolArray[21]);

        fakeBoolArray[21] = true;
        // Should define ToString() on a MyBool,
        // hence the !! to force bool
        Console.Out.WriteLine("Assigning true again worked: " 
                              + !!fakeBoolArray[21]);
}

This pattern is applicable to all value types. One could for example map 0 to 4 for ints if initialization with 4 was desired etc.

I'd love to make a template of it as would be possible in C++, providing the seed value as template parameter, but I understand that's not possible in C#. Or am I missing something? (Of course in C++ mapping is not necessary at all because one can provide a default ctor which will be called for array elements.)

FWIW, here's a C++ equivalent: https://ideone.com/wG8yEh .

Solution 21 - C#

If you can invert your logic you can use the Array.Clear() method to set the boolean array to false.

        int upperLimit = 21;
        double optimizeMe = Math.Sqrt(upperLimit);

        bool[] seiveContainer = new bool[upperLimit];
        Array.Clear(seiveContainer, 0, upperLimit);

Solution 22 - C#

I am a bit surprised noone has made the very simple, yet ultra fast, SIMD version:

  public static void PopulateSimd<T>(T[] array, T value) where T : struct
  {
     var vector = new Vector<T>(value);
     var i = 0;
     var s = Vector<T>.Count;
     var l = array.Length & ~(s-1);
     for (; i < l; i += s) vector.CopyTo(array, i);
     for (; i < array.Length; i++) array[i] = value;
  }

Benchmark: (Number are for Framework 4.8, but Core3.1 is statistically the same)

Method N Mean Error StdDev Ratio RatioSD
DarthGizka 10 25.975 ns 1.2430 ns 0.1924 ns 1.00 0.00
Simd 10 3.438 ns 0.4427 ns 0.0685 ns 0.13 0.00
DarthGizka 100 81.155 ns 3.8287 ns 0.2099 ns 1.00 0.00
Simd 100 12.178 ns 0.4547 ns 0.0704 ns 0.15 0.00
DarthGizka 1000 201.138 ns 8.9769 ns 1.3892 ns 1.00 0.00
Simd 1000 100.397 ns 4.0965 ns 0.6339 ns 0.50 0.00
DarthGizka 10000 1,292.660 ns 38.4965 ns 5.9574 ns 1.00 0.00
Simd 10000 1,272.819 ns 68.5148 ns 10.6027 ns 0.98 0.01
DarthGizka 100000 16,156.106 ns 366.1133 ns 56.6564 ns 1.00 0.00
Simd 100000 17,627.879 ns 1,589.7423 ns 246.0144 ns 1.09 0.02
DarthGizka 1000000 176,625.870 ns 32,235.9957 ns 1,766.9637 ns 1.00 0.00
Simd 1000000 186,812.920 ns 18,069.1517 ns 2,796.2212 ns 1.07 0.01

As can be seen, it is much faster at <10000 elements, and only slightly slower beyond that.

Solution 23 - C#

There are some more answers on this (duplicate?) question: https://stackoverflow.com/questions/1897555/what-is-the-equivalent-of-memset-in-c

Someone has benchmarked the alternatives (they included an unsafe version, but they didn't try memset): http://techmikael.blogspot.co.uk/2009/12/filling-array-with-default-value.html

Solution 24 - C#

Here is another appraoch with System.Collections.BitArray which has such a constructor.

bool[] result = new BitArray(1000000, true).Cast<bool>().ToArray();

or

bool[] result = new bool[1000000];
new BitArray(1000000, true).CopyTo(result, 0);

Solution 25 - C#

Make a private class inside where you make the array and the have a getter and setter for it. Unless you need each position in the array to be something unique, like random, then use int? as an array and then on get if the position is equal null fill that position and return the new random value.

IsVisibleHandler
{

  private bool[] b = new bool[10000];

  public bool GetIsVisible(int x)
  {
  return !b[x]
  }

  public void SetIsVisibleTrueAt(int x)
  {
  b[x] = false //!true
  }
}

Or use

public void SetIsVisibleAt(int x, bool isTrue)
{
b[x] = !isTrue;
}

As setter.

Solution 26 - C#

Boolean[] data = new Boolean[25];

new Action<Boolean[]>((p) => { BitArray seed = new BitArray(p.Length, true); seed.CopyTo(p, 0); }).Invoke(data);

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionpatjbsView Question on Stackoverflow
Solution 1 - C#RonyView Answer on Stackoverflow
Solution 2 - C#JaredParView Answer on Stackoverflow
Solution 3 - C#bytebenderView Answer on Stackoverflow
Solution 4 - C#juFoView Answer on Stackoverflow
Solution 5 - C#LBushkinView Answer on Stackoverflow
Solution 6 - C#MrFoxView Answer on Stackoverflow
Solution 7 - C#bashmohandesView Answer on Stackoverflow
Solution 8 - C#patjbsView Answer on Stackoverflow
Solution 9 - C#Panos TheofView Answer on Stackoverflow
Solution 10 - C#Petar PetrovView Answer on Stackoverflow
Solution 11 - C#l33tView Answer on Stackoverflow
Solution 12 - C#Eric J.View Answer on Stackoverflow
Solution 13 - C#Apollo3zehnView Answer on Stackoverflow
Solution 14 - C#Joe HuangView Answer on Stackoverflow
Solution 15 - C#Shubham SharmaView Answer on Stackoverflow
Solution 16 - C#Stan R.View Answer on Stackoverflow
Solution 17 - C#JamesView Answer on Stackoverflow
Solution 18 - C#DarthGizkaView Answer on Stackoverflow
Solution 19 - C#DouglasView Answer on Stackoverflow
Solution 20 - C#Peter - Reinstate MonicaView Answer on Stackoverflow
Solution 21 - C#superstewieView Answer on Stackoverflow
Solution 22 - C#CineView Answer on Stackoverflow
Solution 23 - C#RichView Answer on Stackoverflow
Solution 24 - C#fuboView Answer on Stackoverflow
Solution 25 - C#Peter JView Answer on Stackoverflow
Solution 26 - C#ldsmithperrinView Answer on Stackoverflow