2011-07-27 15 views
14

C# kompilator dał mi następujący błądwartość przypisać zmiennej tylko do odczytu w sposób prywatny wywołana tylko przez konstruktorów

CS0191: tylko do odczytu pole nie może być przypisany do (z wyjątkiem konstruktora lub zmiennym inicjatora)

Do Muszę przenieść kod (w mojej prywatnej funkcji) do konstruktora? To brzmi niezręcznie.

Należy zauważyć, że metoda prywatna została przeznaczona wyłącznie do wywołania przez konstruktora. Spodziewam się, że istnieje jakiś atrybut, za pomocą którego mogę oznaczyć odpowiednią metodę.

Odpowiedz

4

Tak. Czy próbowałeś używać łańcuchów konstruktora jako alternatywy dla używania wspólnej metody?

public StuffClass(string a, char b, int c) 
{ 
    _a = a; 
    _b = b; 
    _c = c; 
} 

public StuffClass(string a, char b) 
    : this(a, b, 2) 
{} 
+0

Metoda prywatny był przeznaczony tylko do być nazywane przez konstruktora. Spodziewam się, że istnieje jakiś atrybut, za pomocą którego mogę oznaczyć odpowiednią metodę. – tom

+0

@tom - Nie rozumiem, co masz na myśli, jeśli chodzi o atrybut, ale łańcuchy konstruktorów to idiomatyczny sposób wykonywania tego, co opisujesz. –

0

Jeśli chcesz go zmodyfikować, nie powinieneś go czytać tylko w pierwszej kolejności. Gdy zmienna jest tylko do odczytu można modyfikować tylko w konstruktorze lub w momencie deklaracji jak sugeruje błąd

Zgodnie z MSDN

readonly słowo kluczowe jest modyfikator, które można stosować na polach. Gdy deklaracja pola zawiera modyfikator readonly, przypisania do pól wprowadzonych przez deklarację mogą wystąpić tylko jako część deklaracji lub w konstruktorze w tej samej klasie.

1

Członków readonly można przypisywać tylko na poziomie klasy lub na jego konstruktorze. to jest korzyść z używania słowa kluczowego readonly.

class Foo 
{ 
    private readonly Foo _foo = new Foo(); // Valid 

    public Foo() 
    { 
     _foo = new Foo(); // Valid 
    } 

    private void SomeMethod() 
    { 
     _foo = new Foo(); // Not valid 
    } 
} 

Można użyć readonly jako alternatywa dla hasła const przy użyciu klas „inny, że klasa string”, ponieważ kompilator nie pozwoli Ci przypisać const do klas.

4

Pole tylko do odczytu może być przypisane tylko przez konstruktor. Co można zrobić, to zainicjować pole z metody:

class Foo 
{ 
    private readonly Bar _bar = InitializeBar(); 

    private Bar InitializeBar() 
    { 
     // Add whatever logic you need to obtain a Foo instance. 
     return new Bar(); 
    } 
} 
20

Wbrew temu, co inne posty mówią, nie jest rzeczywiście (nieco nietypowy) sposób to zrobić i faktycznie przypisać wartość w metodzie :

public class Foo 
{ 
    private readonly string _field; 

    public Foo(string field) 
    { 
     Init(out _field, field); 
    } 

    private static void Init(out string assignTo, string value) 
    { 
     assignTo = value; 
    } 
} 

Przykład pochodzący od here.

Alternatywnie, można również zwrócić wartość z prywatnej metody i przypisać go w konstruktorze następująco:

class Foo 
{ 
    private readonly string _field; 

    public Foo() 
    { 
     _field = GetField(); 
    } 

    private string GetField() 
    { 
     return "MyFieldInitialization"; 
    } 
}