C#のfalse演算子は何に適していますか?


107

C#には2つの奇妙な演算子があります。

この権利を理解していれば、これらの演算子はブール式の代わりに使用したい型で、ブールへの暗黙の変換を提供したくない場合に使用できます。

次のクラスがあるとします。

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

    }

だから私は次のコードを書くことができます:

    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)

ただし、上記のすべての例では、true演算子のみが実行されます。では、C#のfalse演算子は何に適しているのでしょうか。

注:より多くの例を見つけることができるここではここここ


最新のドキュメントはdocs.microsoft.com/en-us/dotnet/csharp/language-reference/…にあります。C#2.0がnull許容型を追加して以来、ドキュメントはこの演算子を定義する理由はもうないことを示唆しています。
Mark Amery 2017

回答:


65

これを使用して、&&and ||演算子をオーバーライドできます。

&&そして||、オペレータは、オーバーライドすることはできませんが、あなたがオーバーライドする場合は|&trueそしてfalse正確に正しい方法でコンパイラが呼び出されます|&、あなたが書くとき||&&

たとえば、次のコードを見てくださいhttp://ayende.com/blog/1574/nhibernate-criteria-api-operator-overloadingから-このトリックについて知りました。@ 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;
}

これは明らかに副作用であり、意図された使用方法ではありませんが、便利です。


あなたのリンクは404です。これをどのように編集するかわからないので、そのままにしておきます。
user7116

アーカイブされたコピーを使用してURLを更新し、引き続き読み取れるようにしました。
IAmTimCorey 2011年

25

Shog9とNir:回答ありがとうございます。これらの答えは私にSteve Eichertの記事を示し、それがmsdn示しました

演算x && yはT.false(x)として評価されますか?x:T。&(x、y)。ここで、T.false(x)はTで宣言された演算子falseの呼び出しであり、T。&(x、y)は選択された演算子&の呼び出しです。つまり、xが最初に評価され、結果に対して演算子falseが呼び出されて、xが確実にfalseかどうかが判断されます。次に、xが間違いなくfalseの場合、演算の結果は以前にxに対して計算された値になります。それ以外の場合は、yが評価され、選択された演算子&が、以前にxに対して計算された値とyに対して計算された値に対して呼び出され、演算の結果が生成されます。


彼らが(!T.true(x)) ? x : T.&(x, y)代わりにロジックを使用することを選択しなかったのはなぜでしょうか。
Des Nerger、


7

AFAIK、それは、オペレーターが戦場に&&出たときなど、偽のテストで使用されます。&&ショートサーキットなので覚えておいてください。

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

mFalse.false()が呼び出され、true式が返されると、'mFalse.true()'への呼び出しに縮小されます(これにより、が返されfalseます。そうしないと、奇妙になります)。

あなたが実装しなければならないことに注意してください&、それがあれば使われているので、コンパイルにその発現のための順に演算子をmFalse.false()返しますfalse


3

これは、リンクしたMSDNの記事から、Nullable(つまりint?、bool?など)型がC#2の言語に導入される前に、null可能ブール型を許可するために提供されたようです。したがって、値がtrueであるかfalseであるかnullであるかを示す内部値を格納します。つまり、例では、> 0がtrue、<0がfalse、== 0がnullであり、SQLスタイルのnullセマンティクスが得られます。nullが明示的にチェックされるようにするには、.IsNullメソッドまたはプロパティを実装する必要もあります。

SQLと比較して、値Fooがtrueに設定された3行、値Fooがfalseに設定された3行、および値Fooがnullに設定された3行のテーブルTableを想像してください。

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

すべての行をカウントするには、次のことを行う必要があります:-

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

この「IS NULL」構文では、クラスに.IsNull()と同等のコードが含まれます。

LINQはC#との比較をより明確にします:-

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

MyTypeEnumberableがデータベースの内容とまったく同じであることを想像します。つまり、3つの値がtrue、3つの値がfalse、3つの値がnullです。この場合、totalCountは6と評価されます。ただし、コードを次のように書き直した場合:

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

次に、totalCountは9に評価されます。

リンクされたMSDNのfalse演算子に関する記事に記載されているDBNullの例は、この正確な動作を持つBCLのクラスを示しています。

実際には、このタイプの動作が必要かどうかを完全に確信していない限り、これを使用すべきではないという結論に達しました。はるかに単純なnull可能構文を使用する方が良いです!!

更新:論理演算子を手動でオーバーライドする必要があることに気づきました!、|| &&を使用してこれを適切に機能させます。私は、偽の演算子がこれらの論理演算子にフィードする、つまり、真、偽、または「その他」を示すと考えています。別のコメントで述べたように、!xはそのままでは機能しません。あなたはオーバーロードする必要があります!。変!

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.