2011-12-31 11 views
5

Questo è essenzialmente ciò che voglio fare:Come definire un getter virtuale e un setter astratto per una proprietà?

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); 
     } 
    } 
} 

Il getter per Variable sarà lo stesso in tutte le classi derivate, ma il setter deve essere diverso.

In effetti ... Preferirei non avere classi derivate (è solo una chiamata di funzione che differirà per ogni tipo) ma non riesco a pensare a come altro farlo.


Edit: Se non fosse chiaro quale sia il problema che sto avendo è, sto ottenendo un errore di sintassi:

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

E io non sono sicuro come creare un "accessor set overridable" ... virtual e abstract non sembrano essere consentiti sul setter.

+1

Per quanto riguarda la modifica: è per questo che ho dato la risposta che ho dato. Ho già sconcertato questo problema. –

risposta

8

Non è possibile farlo in C#, ma come soluzione alternativa è possibile farlo. Significherebbe chiamare una funzione setter astratta che potrebbe essere sovrascritta dalle classi derivate, lasciando intatto lo standard. Funzionerebbe?

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ì, funzionerebbe. A spese di una chiamata di funzione virtuale aggiuntiva. –

+0

Soluzione interessante! E ciò costringerebbe le classi derivate a implementare il setter. Non è così pulito, ma è più sicuro. Mi piace! – mpen

+0

Se stai facendo questo, 'Variable' non ha più bisogno di essere virtuale. – Gabe

2

Non è possibile farlo in C#. Devi aggiungere un setter alla classe base e lanciare un'eccezione "Operazione non valida".

+0

Penso che "NotImplementedException" abbia più senso, ma sembra che funzioni adesso: D – mpen

+0

In realtà, potresti avere ragione riguardo all'eccezione; ad esempio, questo è ciò che la classe ReadOnlyCollection genera se si tenta di modificarlo. –

6

Sarà necessario fare questo:

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); 
     } 
    } 
} 

quanto ho capito, sarà l'atteso il comportamento.

Spero che aiuti.

+1

'_variable' dovrebbe essere' value' come hai rimosso il mio backing member, ma abbastanza vicino! Non pensavo di poterlo fare senza uno. – mpen

+0

Ho risolto il problema. Grazie! – ivowiblo

Problemi correlati