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

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

Recibo un error al compilar el código C# anterior.Asignación al campo de solo lectura estático de la clase base

El error dice - "Un campo de sólo lectura estática no se puede asignar a (excepto en un constructor estático o un inicializador de variable)"

Pero yo estoy asignando en un constructor estático.

La necesidad de una variable estática es que la clase base tiene métodos que usan esta variable, pero las clases derivadas y la clase base deben tener valores diferentes para esta variable. Pero el valor es constante en todas las instancias de la clase respectiva. Debe ser de solo lectura porque no debe ser cambiado por ningún lado.

¿Cuál es el error en el código anterior? (Si hay alguno) No parece ser capaz de detectar uno. El mensaje de error no está ayudando. Como no estoy haciendo nada mal según eso.

Si hay un error, ¿cómo puedo implementar esta funcionalidad? Sé que una solución simple sería convertirla en una variable de instancia y asignarles diferentes valores en las clases derivadas. Pero eso es innecesario ya que el valor es constante en todas las instancias de la clase respectiva.

Respuesta

14

Está asignando en el constructor estático erróneo sin embargo. Solo se puede asignar en un constructor estático para el tipo que declara la variable.

Supongamos que tiene otra clase derivada de ClassC que hace lo mismo: terminaría sobrescribiendo la variable, que debe ser de solo lectura. Hay una variable estática única aquí, sin importar cuántas clases derivadas tengas.

Una respuesta es evitar el uso de una estática variables pero poner un virtual propiedad en la clase base, y hacer que cada clase derivada sustituye a la propiedad para devolver una constante diferente:

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

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

Básicamente opción sería separar los bits "estáticos" en una jerarquía separada; de hecho, parece que quieres polimorfismo sobre el tipo en lugar de instancias, y eso no es compatible con .NET.

+1

¡Exactamente! "Polimorfismo sobre el tipo". No creo que pueda ser mejor redactado. Gracias por señalar que no es compatible con .NET. – Poulo

5

En su ejemplo, solo existirá un único campo, el de la clase base y no podrá tener valores diferentes en un solo campo. Además de eso, solo puede inicializar los campos readonly en la misma clase, no en las clases derivadas. Una solución alternativa podría ser la definición de una clase genérica como:

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

y utilizar ProcessNames<DerivedClassType>.Value lugar. Obviamente, el valor será públicamente accesible de esta manera.

Sin embargo, debería ver si la definición del campo en cada clase derivada se ajusta por separado a su necesidad y solo recurrir a soluciones alternativas si no es así.

1

Hay muchas formas de desollar al gato. Aquí hay otra manera de hacerlo.

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

pero esto solo funciona en variables de instancia, lo que realmente no logra lo que se quería –

Cuestiones relacionadas