2009-09-14 10 views
7
public class ClassA 
{ 
    public static readonly string processName; 
} 

public class ClassB : ClassA 
{ 
    static ClassB() 
    { 
     processName = "MyProcess.exe"; 
    } 
} 

Otrzymuję błąd podczas kompilowania powyższego kodu C#.Przypisywanie do statycznego pola tylko do odczytu w klasie bazowej

Błąd mówi - „statycznego pola tylko do odczytu nie można przypisać (oprócz statycznego konstruktora lub zmiennym inicjatora)”

Ale ja przypisaniem go w statycznym konstruktorze.

Potrzebą takiej statycznej zmiennej jest to, że klasa podstawowa ma metody, które używają tej zmiennej, ale klasy pochodne i klasa bazowa muszą mieć różne wartości dla tej zmiennej. Ale wartość jest stała we wszystkich instancjach danej klasy. Musi być tylko do odczytu, ponieważ nigdzie nie można go zmienić.

Jaki jest błąd w powyższym kodzie? (Jeśli są jakieś), wydaje mi się, że nie jestem w stanie go rozpoznać. Komunikat o błędzie nie pomaga. Ponieważ nie robię nic złego zgodnie z tym.

Jeśli wystąpi błąd, w jaki sposób mogę zaimplementować tę funkcję? Wiem, że prostym rozwiązaniem byłoby uczynienie go zmienną instancji i przypisanie im różnych wartości w klasach pochodnych. Nie jest to jednak konieczne, ponieważ wartość jest stała we wszystkich instancjach danej klasy.

Odpowiedz

14

Mimo to przypisuje się błędny konstruktor statyczny . Może on być przypisany tylko w statycznym konstruktorze dla typu deklarującego zmienną.

Załóżmy, że masz inną klasę wywodzącą się z ClassC, która robi to samo - skończyłoby się nadpisywanie zmiennej, która ma być tylko do odczytu. W tym miejscu istnieje zmienna statyczna pojedyncza, niezależnie od tego, ile masz klas pochodnych.

Jedną z odpowiedzi jest unikać statycznego zmienną ale umieścić wirtualny własność w klasie bazowej i dokonać każda klasa pochodzi zastąpić właściwość, aby powrócić inny Constant:

public class ClassA 
{ 
    public virtual string ProcessName { get { return "ClassAProcess"; } } 
} 

public class ClassB : ClassA 
{ 
    public override string ProcessName { get { return "MyProcess.exe"; } } 
} 

zasadzie opcji byłoby oddzielenie "statycznych" bitów w oddzielnej hierarchii - faktycznie brzmi to tak, jakbyś chciał polimorfizmu zamiast typu, a nie jest on obsługiwany w .NET.

+1

Dokładnie! "Polimorfizm nad typem". Nie sądzę, żeby mogło być lepiej sformułowane. Dzięki za wskazanie, że nie jest on obsługiwany w .NET. – Poulo

5

W twoim przykładzie będzie istniało tylko jedno pole, z klasy bazowej i nie możesz mieć różnych wartości w jednym polu. Oprócz tego można inicjować tylko pola readonly w tej samej klasie, a nie w klasach pochodnych. Rozwiązaniem mogłoby być zdefiniowanie rodzajowe klasy jak:

static class ProcessNames<T> { 
    public static string Value { get; set; } 
} 

i używać ProcessNames<DerivedClassType>.Value zamiast. Oczywiście wartość będzie publicznie dostępna w ten sposób.

Należy jednak sprawdzić, czy zdefiniowanie pola w każdej klasie pochodnej osobno pasuje do potrzeb i można zastosować tylko obejścia, jeśli tak się nie dzieje.

1

Istnieje wiele sposobów na skórze kota. Oto inny sposób, w jaki możesz to zrobić.

public class ClassA 
{ 
    public string ProcessName{ get; private set;} 

    public ClassA() 
    { 
     ProcessName = "ClassAProcess"; 
    } 

    public ClassA(string processName) 
    { 
     ProcessName = processName; 
    } 
} 

public class ClassB : ClassA 
{ 
    public ClassB() : base("ClassAProcess") 
    { 
    } 
} 
+0

ale działa tylko na zmiennych instancji, które tak naprawdę nie osiągają tego, co było potrzebne –

Powiązane problemy