Подтвердить что ты не робот

Является ли статическая переменная-член общей для всех стандартных экземпляров С#?

В С# у меня есть общий класс:

public class MyGeneric<ParameterClass> where ParameterClass: MyGenericParameterClass, new() {
    public static int Variable;
}

Теперь в С++, если я создавал шаблонный класс с разными параметрами, каждый полный класс получил бы его собственный Variable, поэтому я просто не могу сказать

MyGeneric.Variable = 1; // invalid in C++

в С++, но похоже, что я могу сделать это на С#.

Я хотел бы уточнить...

Если у меня есть общий элемент со статической членной переменной, это переменная, разделяемая между всеми генерируемыми экземплярами?

4b9b3361

Ответ 1

Раздел 25.1.4 спецификации языка ECMA С#

Статическая переменная в объявлении общего класса используется совместно все экземпляры одного и того же замкнутого сконструированного типа (§26.5.2), но не разделяемый между экземплярами разных закрытых построенных типов.Эти правила применяются независимо от того, является ли тип статического переменная включает любые параметры типа или нет.

Вы можете увидеть это сообщение в блоге: Статические поля в родовых классах Гас Перес

Вы также не можете сделать это на С#.

MyGeneric.Variable = 1;

Рассмотрим следующий пример из спецификации языка ECMA.

class C<V>
{
    static int count = 0;
    public C()
    {
        count++;
    }
    public static int Count
    {
        get { return count; }
    }
}
class Application
{
    static void Main()
    {
        C<int> x1 = new C<int>();
        Console.WriteLine(C<int>.Count);  // Prints 1 
        C<double> x2 = new C<double>();
        Console.WriteLine(C<double>.Count); // Prints 1 
        Console.WriteLine(C<int>.Count);  // Prints 1 
        C<int> x3 = new C<int>();
        Console.WriteLine(C<int>.Count);  // Prints 2 
    }
}

Ответ 2

MyGeneric<MyClass>.Variable
MyGeneric<MyOther>.Variable

Эти две разные статические переменные, которые рассматриваются как отдельные классы.

Ответ 3

Нет, он не используется.

Каждый класс MyGeneric<T> будет решать другой тип времени выполнения для каждой возможности T.

Пожалуйста, проверьте, нет ли не общего класса MyGeneric со статическим членом Variable.

Ответ 4

Нет, это не так. Родовые типы могут быть "открытыми" или "закрытыми". Открытый тип - это тип List<T>, где параметр type не определен; List<int> является замкнутым типом.

По существу, открытый тип не рассматривается как правильный "Тип" по времени выполнения - только закрытые версии являются истинными типами. Итак, MyGeneric<int> и MyGeneric<string> являются двумя совершенно разными типами и, следовательно, имеют свои собственные экземпляры статической переменной.

Это становится более очевидным из-за того, что вы не можете вызвать свой статический член так, как вы предлагаете: MyGeneric.Variable не будет компилироваться на С#.

Этот код приложения консоли достаточно просто иллюстрирует:

class Program
{
    static void Main(string[] args)
    {
        Test<int>.i = 2;
        Test<string>.i = 8;

        Console.WriteLine(Test<int>.i);   // would write "8" if the fields were shared
        Console.WriteLine(Test<string>.i);
        // Console.WriteLine(Test.i); // does not compile
        // Console.WriteLine(Test<>.i); // does not compile
    }
}

class Test<T>
{
    public static int i;
}