Использование локальной переменной, которой не присвоено значение

Так компилируется:

class Program
{
    delegate void Message();

    private static void GoodMooning()
    {
        Console.WriteLine("Доброе утро");
    }

    private static void GoodEvening()
    {
        Console.WriteLine("Добрый вечер");
    }

    static void Main(string[] args)
    {
        Message message;
        if(DateTime.Now.Hour < 12)
        {
            message = GoodMooning;
        }
        else 
        {
            message = GoodEvening;
        }
        Console.WriteLine(DateTime.Now.Hour);
        message();
        Console.ReadKey();
    }       
}

А вот так не компилируется и пишет, что переменная message не инициализирована:

class Program
{
    delegate void Message();

    private static void GoodMooning()
    {
        Console.WriteLine("Доброе утро");
    }

    private static void GoodEvening()
    {
        Console.WriteLine("Добрый вечер");
    }

    static void Main(string[] args)
    {
        Message message;
        int a = 2;
        if(a < 12)
        {
            message = GoodMooning;
        }
        message();
        Console.ReadKey();
    }       
}

Ответы (3 шт):

Автор решения: NaClnik

В первом варианте компилируется, потому что до вызова делегата, он в любом случае получает значение, а во втором варианте message получит значение только в случае если сработает условие DateTime.Now.Hour < 12, поэтому компиляция и не происходит. По идее, message можно просто проинициализировать null и код скомпилируется.

→ Ссылка
Автор решения: Proshka

По-моему, вот как работает CLR в данном случае. Вычисление значения текущего времени происходит позже, чем проверяется инициализация объекта делегата. Почему? Потому что при установке явного значения if(true) - код компилируется без ошибок.

 class Program
{
    delegate void Message();

    private static void GoodMooning()
    {
        Console.WriteLine("Доброе утро");
    }

    private static void GoodEvening()
    {
        Console.WriteLine("Добрый вечер");
    }

    static void Main(string[] args)
    {
        Message message;
        if(true)
        {
            message = GoodMooning;
        }

        message();

        Console.ReadKey();
    }
→ Ссылка
Автор решения: aepot

Если бы a была константой, скомпилировался бы.

const int a = 2;

А значения переменных - не во власти компилятора, потому что они определяются при запуске приложения, а не компиляции.

Компилятор просто не знает, какой будет результат выполнения условия, поэтому и предупреждает вас о том, что переменная не инициализирована. Вы можете это исправить.

Message message = null;

Либо можно вынести эту переменную в поле из метода, тогда она получит значение по умолчанию автоматически.

private static Message message;

Есть еще одно решение, если вы точно уверены, что условие выполнится при запуске приложения, можно успокоить компилятор бросив исключение. Вы как бы точно знаете, что оно не будет выброшено, а компилятор будет точно знать, что непроинициализированная переменная не будет использована - все довольны.

Message message;
int a = 2;
if (a < 12)
{
    message = GoodMooning;
}
else
    throw new Exception("Вот сейчас совсем неожиданно было");
message();

Документация.

→ Ссылка