Domanda

Ci sono due strane operatori in C#:

Se ho capito bene in questi operatori possono essere utilizzati in tipi che voglio usare al posto di una espressione booleana e dove non voglio fornire una conversione implicita di tipo bool.

Diciamo che ho una classe che segue:

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

    }

Così 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 di cui sopra solo il vero operatore viene eseguito.Così che cosa è l'operatore false in C# buona per?

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

È stato utile?

Soluzione

È possibile utilizzarlo per sostituire la && e || operatori.

Il && e || gli operatori non possono essere sostituiti, ma se si esegue l'override |, &, true e false nel giusto modo il compilatore chiamata | e & quando si scrive || e &&.

Per esempio, guardate 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;
}

Ovviamente questo è un effetto collaterale e non il modo in cui è destinato a essere utilizzato, ma è utile.

Altri suggerimenti

Shog9 e Nir:grazie per le vostre risposte.Quelle risposte che mi ha indicato Steve Eichert articolo e mi ha indicato msdn:

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

La pagina link http://msdn.microsoft.com/en-us/library/6x6y6z4d.aspx dice quello che erano, che era un modo di trattare la nullable bools prima nullable tipi di valore sono state introdotte.

Credo che oggi stanno bene per lo stesso genere di cose come ArrayList - cioèassolutamente nulla.

Per quanto ne so, non dovrebbe essere utilizzato in una prova falsa, come quando il && operatore entra in gioco.Ricordate, && i corto-circuiti, così nell'espressione

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

mFalse.false() è chiamato, e al ritorno true l'espressione è ridotta in appello a 'mFalse.vero()' (che dovrebbe poi tornare false, o cose strane).

Si noti che è necessario implementare l' & operatore per l'espressione di compilare, dal momento che è utilizzato se mFalse.false() restituisce false.

Sembra dall'articolo di MSDN è collegato ad esso è stato fornito per consentire nullable i tipi boolean prima Nullable (es.int?, bool?, ecc.) tipo di essere introdotti nel linguaggio C#2.Così si può memorizzare un valore che indica se il valore è true o false o null, cioènel tuo esempio >0 per vero, <0 per falso e ==0 per nulla, e poi devi avere SQL stile null semantica.È inoltre necessario implementare un .IsNull metodo o una proprietà in modo che la nullità può essere controllato in modo esplicito.

Il confronto di SQL, immaginate una tabella con 3 righe con valore di Pippo impostata su true, 3 righe con valore di Pippo false e 3 righe con valore di Pippo impostato su null.

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

Per contare tutte le righe è necessario effettuare le seguenti operazioni:-

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

Questo 'È NULL' la sintassi sarebbe equivilent di codice nella vostra classe .IsNull().

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

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

Immaginando che MyTypeEnumberable ha esattamente lo stesso contenuto del database, ad esempio3 valori uguale a true, 3 valori uguale a false e 3 i valori uguali a null.In questo caso totalCount, di valutare a 6 in questo caso.Tuttavia, se abbiamo ri-scritto il codice come:-

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

Quindi totalCount, di valutare a 9.

Il DBNull esempio dato collegate articolo di MSDN sulla falsa operatore dimostra classe nell'BCL che ha questo comportamento.

In effetti, in conclusione, non si dovrebbe usare se non siete completamente sicuri che si desidera questo tipo di comportamento, è meglio usare il più semplice fino nullable sintassi!!

Aggiornamento: Ho appena notato che hai bisogno di sostituire manualmente la logica operatori !, || e && per fare questo lavoro correttamente.Credo che l'operatore false alimenta questi operatori logici, cioèindicando la verità, la falsità o 'altrimenti'.Come osservato in un altro commento !x non lavorare fuori il pipistrello;devi sovraccarico !.La stranezza!

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