Ottenimento della contravarianza conforme a Liskov negli argomenti del metodo in C #

0

Cercando di praticare LSP, il seguente non mi è chiaro:

Liskov requirements (some)
-There must be contravariance of the method arguments in the subtype.
– There must be covariance of the return types in the subtype.

Anche il metodo in una sottoclasse può essere dichiarato con un tipo di parametro più generico rispetto alla classe base, giusto? Ma per quanto ne so, non funziona, come ho provato in C #:

class A
{
    public virtual void Test(Cat a)
    { }

}

class B : A
{
    public override void Test(Animal a)  //shouldn't this work to be Liskov compliant?
    {

    }
}

class Animal
{ }

class Cat : Animal
{ }

Poiché, per quanto ne so, CLR non supporta la covarianza tranne i delegati e i generici, come possiamo implementare un codice veramente conforme a LSP se questo non può essere soddisfatto?

    
posta Ezoela Vacca 29.01.2018 - 16:19
fonte

2 risposte

3

C'è un malinteso diffuso tra le regole di sottotitoli. Infatti, in C # puoi scrivere un codice completamente compatibile con LSP, perché:

Subtyping rule for function types: the argument types in the signature must be at least as general as the actual arguments, and the return type must be at least as specific as the actual return type.

Quindi il tuo codice sarà sicuro per quanto riguarda la varianza in quanto i tuoi tipi saranno gli stessi, soddisfacendo la condizione della sottotipizzazione della funzione. Inoltre, un tipo A è anche un sottotipo di se stesso, la relazione è riflessiva.

Liskov estende le regole di sottotipizzazione con regole comportamentali aggiuntive.

    
risposta data 23.11.2018 - 10:24
fonte
0

In questo caso, C # è più conservativo rispetto all'ipotetico, rispetto al tipo dichiarato.

Poiché tutti gli override di Test devono accettare Cat s, non possono rompere l'LSP in questo modo.

Puoi puoi tuttavia romperlo molto facilmente con comportamento

class Tabby : Cat {}

class C : A
{
    public override void Test(Cat a)
    {
        if (!a is Tabby) { throw new Exception("Breaking Old Code"); }
    }
}
    
risposta data 23.11.2018 - 17:04
fonte

Leggi altre domande sui tag