2011-12-31 15 views
5

Esto es esencialmente lo que quiero hacer:¿Cómo definir un getter virtual y un setter abstracto para una propiedad?

public abstract class Uniform<T> 
{ 
    public readonly int Location; 
    private T _variable; 

    public virtual T Variable 
    { 
     get { return _variable; } 
    } 
} 

public class UniformMatrix4 : Uniform<Matrix4> 
{ 
    public override Matrix4 Variable 
    { 
     set 
     { 
      _variable = value; 
      GL.UniformMatrix4(Location, false, ref _variable); 
     } 
    } 
} 

El captador de Variable será el mismo en todas las clases derivadas, pero el colocador tiene que ser diferente.

De hecho ... Preferiría no tener clases derivadas en absoluto (solo es una llamada de función que diferirá para cada tipo) pero no se me ocurre cómo hacerlo.


Editar: Si no está claro cuál es el problema que estoy teniendo es, estoy recibiendo un error de sintaxis:

'UniformMatrix4.Variable.set': cannot override because 'Uniform.Variable' does not have an overridable set accessor

y no estoy seguro de cómo crear un "descriptor de acceso invalidante" ... virtual y abstract parece no estar permitido en el colocador.

+1

En cuanto a su edición: es por eso que di la respuesta que di. He desconcertado sobre este problema antes. –

Respuesta

8

No es posible hacer esto en C#, pero como solución alternativa puede hacerlo. Implicaría llamar a una función abstracta del colocador que podría ser anulada por las clases derivadas, dejando intacto el estándar. ¿Esto funcionaría?

public abstract class Uniform<T> 
{ 
    public readonly int Location; 
    protected T _variable; 

    public T Variable 
    { 
     get { return _variable; } 
     set { SetVariable(value); } 
    } 

    protected abstract void SetVariable(T value); 
} 

public class UniformMatrix4 : Uniform<Matrix4> 
{ 
    public override void SetVariable(Matrix4x4 value) 
    { 
     _variable = value; 
     GL.UniformMatrix4(Location, false, ref _variable); 
    } 
} 
+0

Sí, esto funcionaría. A expensas de una llamada de función virtual adicional. –

+0

¡Solución interesante! Y eso obligaría a las clases derivadas a implementar el setter. No es tan limpio, pero es más seguro. ¡Me gusta! – mpen

+0

Si está haciendo esto, 'Variable' ya no necesita ser virtual. – Gabe

2

No es posible hacer esto en C#. Debes agregar un setter a la clase base y hacer que arroje una excepción de "Operación Inválida".

+0

Creo que 'NotImplementedException' tiene más sentido, pero parece estar funcionando ahora: D – mpen

+0

En realidad, es posible que tenga razón sobre la excepción; por ejemplo, eso es lo que arroja la clase ReadOnlyCollection si intenta modificarlo. –

6

Tendrá que hacer esto:

public abstract class Uniform<T> 
{ 
    public readonly int Location; 

    public virtual T Variable 
    { 
     get; set; 
    } 
} 

public class UniformMatrix4 : Uniform<Matrix4> 
{ 
    public override Matrix4 Variable 
    { 
     get 
     { 
      return base.Variable; 
     } 
     set 
     { 
      base.Variable = value; 
      GL.UniformMatrix4(Location, false, ref value); 
     } 
    } 
} 

Según tengo entendido, se espera que el comportamiento.

Espero que ayude.

+1

'_variable' debe ser' valor' ya que eliminó mi miembro de respaldo, ¡pero lo suficientemente cerca! No pensé que podría hacer esto sin uno. – mpen

+0

Lo arreglé. ¡Gracias! – ivowiblo

Cuestiones relacionadas