2010-04-30 18 views
5

W VB6 istnieją lokalne zmienne statyczne, które zachowują swoje wartości po zakończeniu procedury. To tak, jak przy użyciu publicznych vars, ale w lokalnym bloku. Na przykład:Prywatny statyczny VB6 w C#?

sub count() 
static x as integer 
x = x + 1 
end sub 

Po 10 wzywa x będzie 10. Starałem się wyszukać to samo w .NET (a nawet Java), ale nie było żadnego. Czemu? Czy w jakiś sposób łamie model OOP i czy istnieje sposób na naśladowanie tego.

Odpowiedz

6

najbliżej można dostać jest polem statycznym poza metoda:

private static int x; 
public [static] void Foo() { 
    x++; 
} 

przykład Zamknięcie na żądanie:

using System; 
class Program { 
    private static readonly Action incrementCount; 
    private static readonly Func<int> getCount; 
    static Program() { 
     int x = 0; 
     incrementCount =() => x++; 
     getCount =() => x; 
    } 
    public void Foo() { 
     incrementCount(); 
     incrementCount(); 
     Console.WriteLine(getCount()); 
    } 
    static void Main() { 
     // show it working from an instance 
     new Program().Foo(); 
    } 
} 
+2

Korzystanie z konstruktora statycznego w celu zainicjowania pola uczestnika przy zamknięciu jest prawdopodobnie nieco bliższe pod względem dostępu do zmiennej (w przeciwieństwie do pola statycznego, nie będzie widoczne przez odbicie na klasie lub widoczne dla innych metod klasy) –

+0

@Ben - ciekawe podejście, ale dużo dodatkowej złożoności - przekonanie ludzi do zrozumienia przechwyconych zmiennych jest trudne w najlepszym momencie ;-p –

+1

OK, rozumiem, ale * dlaczego *? Czy w jakiś sposób złamie OOP? – blez

0

Zawsze można używać zmiennych statycznych w klasie w tym celu:

class C 
{ 
    static int x=0; 

    void count() 
    { 
    ++x; // this x gets incremented as you want 
    } 
} 
0

Pamiętam statyczne prywatne w wizualnym podstawowym. Byli fajni dla jakiegoś konkretnego zadania.

Nie ma czegoś takiego w .net. Będziesz musiał trzymać się statycznego poza metodą.

+1

Rzeczywiście było kilka fajnych rzeczy w VB6. – blez

+2

Cóż, są one dostępne w VB.NET (ale nie w C#) ... Jeśli zadeklarujesz Static something As Integer w ramach metody, zachowa się ona jak w VB6. –

0

Często tego rodzaju zmienne są używane do konserwacji iteratorów. C# ma te wbudowane bezpośrednio w język za pomocą słowa kluczowego yield. Oto przykład:

IEnumerable<int> TimesTable(int table) 
{ 
    for (int i=0 ; i<12 ; i++) 
    { 
     yield return i * table; 
    } 
} 

W tym przykładzie tworzymy wartości w tablicy n-razy, gdzie n jest określone przez wywołującego. Możemy to wykorzystać w dowolnym iterator jest używana, tak jak w foreach pętli:

foreach (var value in TimesTable(3)) 
{ 
    Console.Write(""+ value + " "); 
} 

... która produkuje:

3 6 9 12 15 18 21 24 27 30 33 36 

W C++, to mógłby stosować zmienne statyczne jak te można opisane z VB (nie jestem VB facet więc nie wiem składni VB):

int TimesTable(int table) { 
    static i = 1; 
    if (i == 12) { 
     i = 1; 
    } 
    return i++ * table; 
} 

C# wersja jest lepsza niż w C++ (lub VB) równoważne becuase iterator może być odwołany ucho ly i może być wiele iteratorów aktywnych w danym momencie. Te rzeczy nie są prawdziwe dla wersji C++ bez większej pracy dewelopera. Z drugiej strony oznacza to, że jedyny przypadek, gdy coś podobnego do zmiennej statycznej jest poprawne w C# podczas implementacji iteratora, a wartość nie utrzymuje się poza tym zakresem.

Mam nadzieję, że przydaje się wam to.

+0

Tak, jestem świadomy iteratorów, ale to nie jest konkretna rzecz, której potrzebuję, w każdym razie, dzięki. – blez