.Net: Статические конструкторы вызываются при доступе к константе? - PullRequest
5 голосов
/ 11 июня 2011

Так вот что я думаю ...

public class MyClass
{
    public const string MyConstant = "MyConstantValue";

    private static MyClass DefaultInstance;

    static MyClass()
    {
         DefaultInstance = new MyClass();
    }
}

...

NotificationService.RegisterForNotification(MyClass.MyConstant, Callback);

Будет ли это работать или мне нужно использовать что-то вроде static readonly свойство поле для запуска статического конструктора?

Ответы [ 4 ]

4 голосов
/ 11 июня 2011

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

Ваш предложенный обходной путь static readonly должен быть в порядке, хотя readonly предлагает поле, а не свойство. Свойства доступны только для чтения, когда у них нет установщика, ключевое слово readonly не используется.

Простой пример:

class HasSConstructor
{
    internal const int Answer = 42;
    static HasSConstructor()
    {
        System.Console.WriteLine("static constructor running");
    }
}

public class Program
{
    public static void Main()
    {
        System.Console.WriteLine("The answer is " + HasSConstructor.Answer.ToString());
    }
}

Вывод в .NET 4.0:

Ответ 42

Статический конструктор никогда не запускается!

3 голосов
/ 11 июня 2011

Статический конструктор вызывается автоматически перед созданием первого экземпляра или ссылками на любые статические элементы.Смотрите здесь: MSDN: Статические конструкторы

Кстати, константные поля по своей природе статичны, но, как указано, они могут (и, вероятно, будут) заменяться самим значением.

1 голос
/ 11 июня 2011

Статический конструктор не будет вызываться, если вы просто используете открытые константы.Например, рассмотрим этот класс:

class Testo
{
    public const string MyValue = "Hello, world";
    public static readonly int xyzzy;

    static Testo()
    {
        Console.WriteLine("In static constructor");
        xyzzy = 27;
    }
}

Теперь в другом классе выполните:

Console.WriteLine(Testo.MyValue);
Console.WriteLine(Testo.xyzzy);

Ваш вывод будет:

Hello, world
In static constructor
27

Константы поднятыиз класса во время компиляции.Таким образом, значение Testo.MyValue не ссылается на класс Testo во время выполнения.Статический конструктор не вызывается до тех пор, пока вы не вызовете что-то, требующее инициализации.

Так что, да, вам нужно получить доступ к чему-то вроде static readonly, если вы хотите убедиться, что конструктор вызывается.

0 голосов
/ 11 июня 2011

Нет, тебе не нужно такое.Статический конструктор вызывается при загрузке класса.

...