c # static в абстрактном суперклассе будет совместно использоваться подклассами? - PullRequest
3 голосов
/ 18 мая 2011

Я пишу некоторые обработчики ashx, которые подключены к фиктивному сервису, и я хочу, чтобы они поделились экземпляром фиктивного сервиса. Самый простой подход, который я создал, - это создание статического экземпляра

.
public class AbstractHandler
    {
        static IService _impl;
        public static IService Impl
        {
            get
            {
                if (_impl == null)
                {
                    _impl = new MockService();
                }
                return _impl;
            }
        }
    }

Однако мне интересно, сработает ли это вообще; будут ли разные обработчики, которые наследуют от этого класса, иметь собственную статическую ссылку _impl, или они будут разделены?

1 Ответ

6 голосов
/ 18 мая 2011

Статическое поле существует один раз, за ​​исключением случая универсального типа, и в этом случае оно существует один раз для каждой используемой комбинации универсальных параметров.

Даже если класс является базовым классом, возможно, абстрактным,применяются те же правила.Обратите внимание, что если класс, в котором объявлено поле, не является универсальным, поле будет существовать один раз, даже если потомки являются общими.Правило «один раз за комбинацию ...» вступает в действие только в том случае, если класс, который объявляет статическое поле, является общим.

Итак, если ваш вопрос вместо этого был:

Как сделать так, чтобы статическое поле было для каждого потомка, а не только один раз

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

Пример LINQPad сценарий для демонстрации «однократной комбинации параметров»:

void Main()
{
    var i = new Test<int>();
    var s = new Test<string>();

    Test<bool>.UsageCount.Dump();
    Test<int>.UsageCount.Dump();
    Test<string>.UsageCount.Dump();
}

public class Test<T>
{
    public static int UsageCount;

    public Test()
    {
        UsageCount++;
    }
}

Вывод:

0
1
1

Пример для демонстрации с основаниемкласс:

void Main()
{
    var i = new Test1();
    var s = new Test2();

    Test1.UsageCount.Dump();
    Test2.UsageCount.Dump();
    Test3.UsageCount.Dump();
}

public abstract class Base<T>
{
    public static int UsageCount;

    protected Base()
    {
        UsageCount++;
    }
}

public class Test1 : Base<Test1>
{
}

public class Test2 : Base<Test2>
{
}

public class Test3 : Base<Test3>
{
}

Выход:

1
1
0
...