Search code examples
c#windows-runtime.net-native

.NET Native optimization breaks an application


In one of the applications I've encountered an error associated with the optimization of code.

I tried to repeat this behavior in the test application. The application is available on GitHub: https://github.com/altk/NullableError

The error occurs only when you compile using .NET Native, but not everywhere. Error reproduces on few PCs.

The application code is very simple. It must prints to the console:

-------------- ELSE --------------
-------------- SUCCESS --------------

But by reason of the optimization it prints:

-------------- ELSE --------------
-------------- FAIL --------------

All code of the application:

#define DEBUG
using System;
using System.Collections.Generic;
using System.Diagnostics;

namespace NullableError
{
    sealed partial class App
    {
        private readonly Dictionary<String, String> _dictionary = new Dictionary<String, String>();

        public App()
        {
            InitializeComponent();

            Execute();
            Exit();
        }

        private Int64? NullableInt64
        {
            get
            {
                var resultString = this[nameof(NullableInt64)];
                return String.IsNullOrEmpty(resultString) ? default(Int64?) : Int64.Parse(resultString);
            }
            //-----FIX VARIANT------
            //UNCOMMENT NEXT LINE TO FIX 
            //[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoOptimization)]
            set
            {
                //-----FIX VARIANT------
                //REPLACE WITH 
                //this[nameof(NullableInt64)] = value != null ? value.Value.ToString() : null;
                this[nameof(NullableInt64)] = value?.ToString();
            }
        }

        private Int64? AnotherNullableInt64
        {
            get
            {
                var resultString = this[nameof(AnotherNullableInt64)];
                return String.IsNullOrEmpty(resultString) ? default(Int64?) : Int64.Parse(resultString);
            }
            set { this[nameof(AnotherNullableInt64)] = value?.ToString(); }
        }

        private void Execute()
        {
            //-----FIX VARIANT------
            //REPLACE WITH IF-ELSE WITH
            //NullableInt64 = (DateTimeOffset.Now - DateTimeOffset.MinValue).TotalMilliseconds < 0 ? (Int64?) 125 : null;
            if ((DateTimeOffset.Now - DateTimeOffset.MinValue).TotalMilliseconds < 0)
            {
                Debug.WriteLine("-------------- IF --------------");
                NullableInt64 = 125;
            }
            else
            {
                Debug.WriteLine("-------------- ELSE --------------");
                NullableInt64 = null;
            }

            //-----FIX VARIANT------
            //REPLACE WITH 
            //AnotherNullableInt64 = 0;
            AnotherNullableInt64 = null;

            Debug.WriteLine(String.Format("-------------- {0} --------------", this[nameof(NullableInt64)] == "0" ? "FAIL" : "SUCCESS"));
        }

        private String this[String key]
        {
            get
            {
                String result;
                return _dictionary.TryGetValue(key, out result) ? result : null;
            }
            set { _dictionary[key] = value; }
        }
    }
}

Solution

  • Microsoft confirmed this bug. https://connect.microsoft.com/VisualStudio/feedback/details/2164313/net-native-optimization-breaks-an-application#

    It will be fixed in upcoming VS 2015 Update 2