Do czego służy operator false W C#?

W C#są dwa dziwne operatory:

Jeśli rozumiem to prawo, operatory te mogą być używane w typach, których chcę użyć zamiast wyrażenia boolowskiego i gdzie nie chcę dostarczać domyślnej konwersji do bool.

Powiedzmy, że mam następującą klasę:

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

    }

Więc mogę napisać następujący kod:

    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)

Jednak dla wszystkich przykładów powyżej wykonywany jest tylko operator true. Do czego służy fałszywy operator w C#?

Uwaga: więcej przykładów można znaleźć tutaj, tutaj i tutaj .

 107
Author: Jakub Šturc, 2008-08-28

5 answers

Można go użyć do nadpisania operatorów && i ||.

Operatory && i || nie mogą być nadpisane, ale jeśli nadpisujesz |, &, true i false dokładnie w odpowiedni sposób kompilator wywoła | i &, gdy napiszesz || i &&.

Na przykład, spójrz na ten kod (z http://ayende.com/blog/1574/nhibernate-criteria-api-operator-overloading - gdzie dowiedziałam się o tej sztuczce; wersja zarchiwizowana przez @ 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;
}

Jest to oczywiście efekt uboczny, a nie sposób, w jaki ma być stosowany, ale jest przydatny.

 65
Author: Nir,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-19 13:06:01

Shog9 i Nir: dzięki za odpowiedzi. Te odpowiedzi wskazywały mi artykuł Steve ' a Eicherta i wskazywały na msdn :

Operacja x && y jest oceniana jako T. false(x) ? x: T. & (X, y), gdzie T. false (X) jest wywołaniem operatora false zadeklarowanego w T, A T.&(X, y) jest wywołaniem wybranego operatora &. Innymi słowy, x jest najpierw obliczany, a operator false jest wywoływany na wyniku, aby określić, czy X jest zdecydowanie false. Wtedy, jeśli x jest definitywnie false, wynikiem operacji jest wartość wcześniej obliczona dla x. w przeciwnym razie obliczana jest wartość y, a wybrany operator & jest wywoływany na wartości wcześniej obliczonej dla x i wartości obliczonej dla y, aby uzyskać wynik operacji.

 25
Author: Jakub Šturc,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-03 16:12:53

Strona, do której linkujesz http://msdn.microsoft.com/en-us/library/6x6y6z4d.aspx mówi, po co one były, co było sposobem obsługi nullable bools przed wprowadzeniem typów wartości nullable.

Domyślam się, że w dzisiejszych czasach nadają się do tego samego rodzaju rzeczy, co ArrayList - czyli absolutnie nic.

 14
Author: Will Dean,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-28 20:28:54

AFAIK, będzie używany w teście na false, np. gdy w grę wchodzi operator &&. Pamiętaj, & & zwarcia, więc w wyrażeniu

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

mFalse.false() jest wywołane, a po zwróceniu true wyrażenie jest zredukowane do wywołania do ' mFalse.true ()' (które następnie powinno zwrócić false, w przeciwnym razie zrobi się dziwnie).

Zauważ, że musisz zaimplementować operator & w celu kompilacji tego wyrażenia, ponieważ jest on używany, jeśli mFalse.false() zwraca false.

 7
Author: Shog9,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-01 11:47:15

Wynika z artykułu MSDN, z którym się z nim łączyłeś, który został dostarczony, aby zezwolić na nullable typu boolean przed Nullable(tj. int? bool?, itd.) Typ wprowadzany do języka w C # 2. W ten sposób przechowywałbyś wewnętrzną wartość wskazującą, czy wartość jest true, false lub null, tzn. w twoim przykładzie >0 dla true,

W porównaniu do SQL, wyobraź sobie tabelę Table z 3 wierszami z wartością Foo ustawioną na true, 3 wierszami z wartością Foo ustawioną na false I 3 wierszami z wartością Foo ustawioną na null.

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

Aby policzyć wszystkie wiersze, musisz wykonać następujące czynności: -

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

Ta składnia 'IS NULL' miałaby równy kod w twojej klasie as .IsNull ().

LINQ sprawia, że porównanie do C# jest jeszcze wyraźniejsze:-

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

Wyobrażając sobie, że MyTypeEnumberable ma dokładnie tę samą zawartość bazy danych, tzn. 3 wartości równe true, 3 wartości równe false oraz 3 wartości równe null. W tym przypadku totalCount będzie oceniać do 6 w tym przypadku. Jeśli jednak przepisamy kod jako: -

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

Wtedy totalCount będzie oceniać Do 9.

Przykład DBNull podany w linkowanym artykule MSDN na temat operatora false pokazuje klasę w BCL, która ma dokładnie takie zachowanie.

W efekcie wniosek jest taki, że nie powinieneś tego używać, chyba że jesteś całkowicie pewien, że chcesz tego typu zachowania, lepiej jest po prostu użyć znacznie prostszej składni nullable!!

Update: zauważyłem, że musisz ręcznie nadpisać operatory logiczne !, / / i & & aby to działało poprawnie. Wierzę, że operator fałszywy wchodzi w te operatory logiczne, tj. wskazując prawdę, fałsz lub "inaczej". Jak zaznaczono w innym komentarzu !x nie będzie działać na kij; trzeba przeciążać !. Dziwactwo!

 3
Author: ljs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-28 20:51:47