A cosa serve l'operatore false in C #?


107

Ci sono due strani operatori in C #:

Se capisco questo diritto, questi operatori possono essere utilizzati nei tipi che desidero utilizzare al posto di un'espressione booleana e in cui non voglio fornire una conversione implicita in bool.

Diciamo che ho una classe seguente:

    public class MyType
    {
        public readonly int Value;

        public MyType(int value)
        {
            Value = value;
        }

        public static bool operator true (MyType mt)
        {
            return  mt.Value > 0;
        }

        public static bool operator false (MyType mt)
        {
            return  mt.Value < 0;
        }

    }

Quindi posso scrivere il seguente codice:

    MyType mTrue = new MyType(100);
    MyType mFalse = new MyType(-100);
    MyType mDontKnow = new MyType(0);

    if (mTrue)
    {
         // Do something.
    }

    while (mFalse)
    {
        // Do something else.
    }

    do
    {
        // Another code comes here.
    } while (mDontKnow)

Tuttavia, per tutti gli esempi precedenti viene eseguito solo l'operatore true. Allora a cosa serve l'operatore false in C #?

Nota: altri esempi possono essere trovati qui , qui e qui .


La documentazione moderna è disponibile su docs.microsoft.com/en-us/dotnet/csharp/language-reference/… . I documenti suggeriscono che non esiste più alcun motivo per definire questo operatore poiché C # 2.0 ha aggiunto tipi nullable.
Mark Amery

Risposte:


65

Puoi usarlo per sovrascrivere gli operatori &&e ||.

Gli &&e ||gli operatori non può essere ignorata, ma se si ignora |, &, trueed falseesattamente nel modo giusto il compilatore chiameranno |e &quando si scrive ||e &&.

Ad esempio, guarda questo codice (da http://ayende.com/blog/1574/nhibernate-criteria-api-operator-overloading - dove ho scoperto questo trucco; versione archiviata da @BiggsTRC):

public static AbstractCriterion operator &(AbstractCriterion lhs, AbstractCriterion rhs)
{
       return new AndExpression(lhs, rhs);
}

public static AbstractCriterion operator |(AbstractCriterion lhs, AbstractCriterion rhs)
{
       return new OrExpression(lhs, rhs);
}

public static bool operator false(AbstractCriterion criteria)
{
       return false;
}
public static bool operator true(AbstractCriterion criteria)
{
       return false;
}

Questo è ovviamente un effetto collaterale e non il modo in cui è inteso essere utilizzato, ma è utile.


il tuo link è 404. Non sono sicuro di come vuoi modificarlo, quindi l'ho lasciato così.
user7116

Ho aggiornato l'URL con una copia archiviata in modo che possa ancora essere letto.
IAmTimCorey

25

Shog9 e Nir: grazie per le vostre risposte. Quelle risposte mi hanno indirizzato all'articolo di Steve Eichert e mi hanno indirizzato a msdn :

L'operazione x && y viene valutata come T.false (x)? x: T. & (x, y), dove T.false (x) è un'invocazione dell'operatore false dichiarato in T, e T. & (x, y) è un'invocazione dell'operatore selezionato &. In altre parole, x viene prima valutato e l'operatore false viene invocato sul risultato per determinare se x è decisamente falso. Quindi, se x è decisamente falso, il risultato dell'operazione è il valore precedentemente calcolato per x. Altrimenti, y viene valutato e l'operatore selezionato & viene richiamato sul valore precedentemente calcolato per x e il valore calcolato per y per produrre il risultato dell'operazione.


Mi chiedo perché non abbiano scelto di usare (!T.true(x)) ? x : T.&(x, y)invece la logica.
Des Nerger


7

Per quanto ne so, sarebbe usato in un test per falso, come quando l' &&operatore entra in gioco. Ricorda, && cortocircuiti, quindi nell'espressione

if ( mFalse && mTrue) 
{
   // ... something
}

mFalse.false()viene chiamato, e al ritorno truel'espressione viene ridotta a una chiamata a 'mFalse.true ()' (che dovrebbe poi tornare false, o le cose diventeranno strane).

Notare che è necessario implementare l' &operatore affinché quell'espressione venga compilata, poiché viene utilizzata se mFalse.false()restituisce false.


3

Sembra che dall'articolo MSDN a cui sei collegato sia stato fornito per consentire tipi booleani nullable prima che il tipo Nullable (cioè int ?, bool ?, ecc.) Venga introdotto nel linguaggio in C # 2. Quindi memorizzeresti un valore interno che indica se il valore è vero o falso o nullo, cioè nel tuo esempio> 0 per vero, <0 per falso e == 0 per nullo, e quindi otterrai una semantica nulla in stile SQL. Dovresti anche implementare un metodo o una proprietà .IsNull in modo che la nullità possa essere verificata esplicitamente.

Confrontando con SQL, immagina una tabella Tabella con 3 righe con valore Foo impostato su true, 3 righe con valore Foo impostato su false e 3 righe con valore Foo impostato su null.

SELECT COUNT(*) FROM Table WHERE Foo = TRUE OR Foo = FALSE
6

Per contare tutte le righe devi fare quanto segue: -

SELECT COUNT(*) FROM Table WHERE Foo = TRUE OR Foo = FALSE OR Foo IS NULL
9

Questa sintassi "IS NULL" avrebbe un codice equivalente nella tua classe come .IsNull ().

LINQ rende il confronto con C # ancora più chiaro: -

int totalCount = (from s in MyTypeEnumerable
                 where s || !s
                 select s).Count();

Immaginare che MyTypeEnumberable abbia esattamente lo stesso contenuto del database, cioè 3 valori uguali a true, 3 valori uguali a false e 3 valori uguali a null. In questo caso totalCount restituirebbe 6 in questo caso. Tuttavia, se riscriviamo il codice come: -

int totalCount = (from s in MyTypeEnumerable
                 where s || !s || s.IsNull()
                 select s).Count();

Quindi totalCount restituirà 9.

L'esempio DBNull fornito nell'articolo MSDN collegato sull'operatore false mostra una classe nel BCL che ha questo comportamento esatto.

In effetti la conclusione è che non dovresti usarlo a meno che tu non sia completamente sicuro di volere questo tipo di comportamento, è meglio usare solo la sintassi nullable molto più semplice !!

Aggiornamento: ho appena notato che devi sovrascrivere manualmente gli operatori logici!, || e && per farlo funzionare correttamente. Credo che l'operatore falso alimenta questi operatori logici, ad esempio indicando verità, falsità o "altrimenti". Come notato in un altro commento! X non funzionerà immediatamente; devi sovraccaricare! Stranezza!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.