Frage

Es gibt zwei seltsame Operatoren in C#:

Wenn ich das richtig verstehe, können diese Operatoren in Typen verwendet werden, die ich anstelle eines booleschen Ausdrucks verwenden möchte und bei denen ich keine implizite Konvertierung in bool bereitstellen möchte.

Nehmen wir an, ich habe folgende Klasse:

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

    }

So kann ich den folgenden Code schreiben:

    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)

Für alle obigen Beispiele wird jedoch nur der wahre Operator ausgeführt.Wozu also ist der False-Operator in C# gut?

Notiz:Weitere Beispiele finden Sie hier Hier, Hier Und Hier.

War es hilfreich?

Lösung

Sie können es verwenden, um das zu überschreiben && Und || Betreiber.

Der && Und || Operatoren können nicht überschrieben werden, aber wenn Sie überschreiben |, &, true Und false genau so, wie der Compiler ihn aufruft | Und & wenn du schreibst || Und &&.

Schauen Sie sich zum Beispiel diesen Code an (von http://ayende.com/blog/1574/nhibernate-criteria-api-operator-overloading - wo ich von diesem Trick erfahren habe; archivierte Version von @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;
}

Dies ist offensichtlich ein Nebeneffekt und nicht die Art und Weise, wie es verwendet werden soll, aber es ist nützlich.

Andere Tipps

Shog9 und Nir:Danke für deine Antworten.Diese Antworten haben mich darauf hingewiesen Artikel von Steve Eichert und es hat mich darauf hingewiesen msdn:

Die Operation x && y wird als T.false(x) ausgewertet?X :T.&(x, y), wobei T.false(x) ein Aufruf des in T deklarierten Operators false ist und T.&(x, y) ein Aufruf des ausgewählten Operators & ist.Mit anderen Worten: x wird zuerst ausgewertet und der Operator „false“ wird auf das Ergebnis angewendet, um zu bestimmen, ob x definitiv falsch ist.Wenn x dann definitiv falsch ist, ist das Ergebnis der Operation der zuvor für x berechnete Wert.Andernfalls wird y ausgewertet und der ausgewählte Operator & wird für den zuvor für x und den für y berechneten Wert aufgerufen, um das Ergebnis der Operation zu erzeugen.

Die Seite, auf die Sie verlinken http://msdn.microsoft.com/en-us/library/6x6y6z4d.aspx sagt, wofür sie gedacht waren, nämlich eine Möglichkeit, mit Nullable-Bools umzugehen, bevor Nullable-Werttypen eingeführt wurden.

Ich würde vermuten, dass sie heutzutage für die gleichen Dinge gut sind wie ArrayList – d. h.absolut gar nichts.

AFAIK, es würde in einem Test auf falsch verwendet werden, beispielsweise wenn das && Der Betreiber kommt ins Spiel.Denken Sie daran, && Kurzschlüsse, also im Ausdruck

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

mFalse.false() wird gerufen, und bei der Rückkehr true Der Ausdruck wird auf einen Aufruf von „mFalse.true()“ reduziert (der dann zurückgegeben werden sollte false, sonst wird es seltsam).

Beachten Sie, dass Sie Folgendes implementieren müssen & Operator, damit dieser Ausdruck kompiliert werden kann, da er if verwendet wird mFalse.false() kehrt zurück false.

Aus dem MSDN-Artikel, auf den Sie verlinkt haben, geht hervor, dass er bereitgestellt wurde, um nullfähige boolesche Typen vor dem Nullable zu ermöglichen (d. h.int?, bool? usw.) werden in C#2 in die Sprache eingeführt.Sie würden also einen internen Wert speichern, der angibt, ob der Wert wahr, falsch oder null ist, d. h.in Ihrem Beispiel >0 für wahr, <0 für falsch und ==0 für null, und dann würden Sie eine Nullsemantik im SQL-Stil erhalten.Sie müssten auch eine .IsNull-Methode oder -Eigenschaft implementieren, damit die Nullität explizit überprüft werden kann.

Stellen Sie sich im Vergleich zu SQL eine Tabelle mit 3 Zeilen vor, deren Wert Foo auf „true“ gesetzt ist, 3 Zeilen mit dem Wert „Foo“ auf „false“ und 3 Zeilen mit dem Wert „Foo“ auf null.

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

Um alle Zeilen zu zählen, müssten Sie Folgendes tun:

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

Diese „IS NULL“-Syntax hätte in Ihrer Klasse den entsprechenden Code wie .IsNull().

LINQ macht den Vergleich zu C# noch deutlicher:-

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

Stellen Sie sich vor, dass MyTypeEnumberable genau den gleichen Inhalt der Datenbank hat, d. h.3 Werte gleich wahr, 3 Werte gleich falsch und 3 Werte gleich null.In diesem Fall würde „totalCount“ 6 ergeben.Wenn wir den Code jedoch wie folgt umschreiben würden:

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

Dann würde totalCount 9 ergeben.

Das DBNull-Beispiel im verlinkten MSDN-Artikel zum False-Operator zeigt eine Klasse in der BCL, die genau dieses Verhalten aufweist.

Tatsächlich ist die Schlussfolgerung, dass Sie dies nicht verwenden sollten, es sei denn, Sie sind völlig sicher, dass Sie dieses Verhalten wünschen. Es ist besser, einfach die weitaus einfachere Nullable-Syntax zu verwenden!

Aktualisieren: Mir ist gerade aufgefallen, dass Sie die logischen Operatoren manuell überschreiben müssen!, || und &&, damit dies richtig funktioniert.Ich glaube, dass der falsche Operator in diese logischen Operatoren einfließt, d. h.Angabe von Wahrheit, Falschheit oder „anders“.Wie in einem anderen Kommentar erwähnt, funktioniert !x nicht auf Anhieb;du musst überladen!.Seltsam!

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top