Domanda

In una classe base ho questa proprietà:

public virtual string Text 
{
    get { return text; }
}

Voglio sovrascriverlo e restituire un testo diverso, ma vorrei anche essere in grado di impostare il testo, quindi ho fatto questo:

public override string Text
{
    get { return differentText; }
    set { differentText = value; }
}

Questo tuttavia non funziona. Ottengo uno squiggly rosso in set che dice che non posso ignorare perché non ha un set accessor. Perché questo aproblema? Cosa devo fare?

È stato utile?

Soluzione

Nel tuo secondo blocco di codice stai creando un metodo set pubblico, ma la parola "quotride override" nella dichiarazione, il compilatore cerca un metodo con la stessa firma nella classe base. Dato che non riesce a trovare quel metodo, non ti permetterà di creare il tuo set.

Come dice ArsenMkrt, è possibile modificare la dichiarazione di base per contenere un set protetto. Ciò ti consentirà di sovrascriverlo, ma poiché non sarai ancora in grado di modificare la firma non puoi promuovere questo metodo come pubblico nella sottoclasse, quindi il codice che hai pubblicato non funzionerà ancora.

Invece devi aggiungere un metodo di set virtuale pubblico alla tua classe base che non fa nulla (o addirittura genera un'eccezione se provi a chiamarlo) ma questo va contro ciò che un utente della classe si aspetterebbe comportarsi così se lo fai (e non lo consiglio) assicurati che sia così ben documentato che l'utente non può perderlo:

///<summary>
///Get the Text value of the object
///NOTE: Setting the value is not supported by this class but may be supported by child classes
///</summary>
public virtual string Text 
{
    get { return text; }
    set { }
}

//using the class

BaseClass.Text = "Wibble";
if (BaseClass.Text == "Wibble")
{
    //Won't get here (unless the default value is "Wibble")
}

In caso contrario, dichiarare il set come metodo separato nella classe figlio:

public override string Text
{
    get { return differentText; }
}

public void SetText(string value)
{
    differentText = value;
}

Altri suggerimenti

public virtual string Text 
{
    get { return text; }
    protected set {}
}

modifica la proprietà della classe base in questo modo, stai provando a sostituire il metodo set che non esiste

Volete esporre più capacità quando usate un tipo figlio. Sembra che tu non voglia scavalcare, tu vuoi oscurare. Usa la nuova parola chiave per nascondere la proprietà Text di sola lettura sotto la tua proprietà leggibile / scrivibile.

Nella classe base:

protected string text;
public string Text 
{
    get { return text; }
}

Nella classe derivata:

new public string Text 
{
    get { return text; }
    set { text = value; }
}

È un problema perché stai rompendo l'incapsulamento. Non puoi sovrascrivere qualcosa e renderlo più accessibile, ciò getterebbe tutto sull'incapsulamento dalla finestra.

Questa è la regola e si applica anche nel tuo caso, anche se stai effettivamente esponendo qualcosa che non è il valore originale.

Non c'è modo di fare esattamente quello che hai tentato. Devi creare un setter nella classe base o utilizzare un metodo diverso per impostare il nuovo valore.

È possibile nascondere la proprietà dalla classe base:

public new string Text
{
    get { return differentText; }
    set { differentText = value; }
}

Ma in quel caso quella proprietà verrà usata solo quando si manipola l'oggetto attraverso una variabile di questo tipo, non il tipo base

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top