Je suis tombé sur un bug particulier ce soir. J'ai donc isolé le bug pour me retrouver au final avec un code particulièrement étrange dont je ne m'explique pas les raisons de son fonctionnement. Donc ne cherchez pas l'utilité en production d'un tel code.

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
using System;
 
namespace BugDouble
{
    class Program
    {
        private static byte[] doubleBytes;
 
        //This version always work
        private static unsafe double ReadDouble01()
        {
            if (doubleBytes.Length < sizeof(double))
                return 0;  
 
            fixed (void* pBuffer = &doubleBytes[0])
                return *((double*)pBuffer); //Don't care about warning, this cast is usefull            
        }
 
        //This version work without the "magic if"
        private static unsafe double ReadDouble02()
        {
            Console.WriteLine("Before If");
            if (doubleBytes.Length < sizeof(double)) //Comment these 2 magic lines to fix the code 
                return 0;
 
            Console.WriteLine("Before Fixed");
            double value = 0;
            fixed (void* pBuffer = &doubleBytes[0])
                value = *((double*)pBuffer);
            Console.WriteLine("After Fixed");
 
            return value;                                   
        }
 
        static void Main(string[] args)
        {
            doubleBytes = BitConverter.GetBytes(1234.56789d);
            Console.WriteLine("ReadDouble01 => {0}", ReadDouble01());
            Console.WriteLine("ReadDouble02 => {0}", ReadDouble02());
            Console.ReadKey();
        }
    }
}
Output :
ReadDouble01 => 1234,56789
Before If
Before Fixed
ReadDouble02 => 0
Si je met en commentaire les 2 lignes suivantes le code fonctionne et les 2 fonctions retournent 1234,56789
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
if (doubleBytes.Length < sizeof(double)) //Comment these 2 magic lines to fix the code 
    return 0;
Comment est ce qu'un if qui retournera toujours true et qui est complètement inutile peut impacter le fonctionnement du code ? Pour ceux qui aurais des doute qu'il passe le if, rappelez vous qu'il affiche "Before Fixed".

ps : Le but est bien de comprendre ce qu'il se passe, et pas de savoir si c'est mieux de faire un "return BitConverter.ToDouble(doubleBytes, 0);"
ps 2 : Il faut cocher la case unsafe dans le projet pour pouvoir le faire tourner