Эмулировать статические переменные функции с использованием потоковых статических полей? - PullRequest
2 голосов
/ 06 ноября 2011

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

Is это хороший способ обойти отсутствие C-подобных статических локальных элементов в C #?

[ThreadStatic]private static int[] staticregister = new int[4];

public static bool CoolStaticMethod(int[] largearray)
{
    //...
}

Я предполагаю, что метод, который не может вызывать сам себя, ни прямо (рекурсивно), ни косвенно, может вызываться только в единственном потоке единственно, поэтому поддельная статическая локальная переменная должна быть объявлена ​​как поток-static и проблема в большей степени решена.

Редактировать:

Я должен добавить, что содержимое регистра является мусором между вызовами методов.

1 Ответ

3 голосов
/ 06 ноября 2011

Это не , что я бы назвал хорошим обходным путем, нет. Это будет работать (при условии, что вы уверены в рисках повторного входа, то есть не вызываете себя, даже через случайные события / обратные вызовы / и т.д.) - но ...

По моему мнению , он с состоянием, делает его экземпляром :

private int[] register = new int[4];
public bool CoolMethod(int[] largearray) {...}

и просто используйте разные экземпляры WheverTheTypeIs для каждого контекста, то есть экземпляр действует в качестве контекста . Просто используйте другой экземпляр для потока, если вы хотите контекст для потока. Это также позволяет продолжить использование обратных вызовов, параллелизма, рабочих и т. Д. В том же контексте . Обратите внимание, что есть много платформ, которые не гарантируют единый поток (WCF, ASP.NET, WPF для примеров), и это будет только увеличиваться, поскольку 5.0 вводит больше async / await -ориентированный код.

Если вы глубоко привязаны к статическим методам, достаточно передать register в качестве второго параметра:

public static bool CoolStaticMethod(int[] largearray, int[] register) {...}

Если проблема заключается в выделении 4-байтового массива:

  1. это обычно будет GEN-0, так дешево собирать
  2. если вы действительно хотите, используйте stackalloc и unsafe, чтобы избежать выделения

Для примера "2":

public static unsafe bool CoolStaticMethod(int[] largearray)
{
    // not an array! this is raw data on the stack; DO NOT GO OUT OF BOUNDS!
    int* register = stackalloc int[4]; 

    register[0] = 1;
    register[1] = largearray[3];
    largearray[2] = register[0];
    ....
}
...