151

ずっと C# を使ってきたにもかかわらず、自分が知らなかったことを見つけることができることにいつも驚かされます...

これについてインターネットで検索してみましたが、検索で「〜」を使用してもうまく機能せず、MSDN でも何も見つかりませんでした (存在しないとは言いません)。

最近このコード スニペットを見ましたが、チルダ (~) の意味は何ですか?

/// <summary>
/// Enumerates the ways a customer may purchase goods.
/// </summary>
[Flags]
public enum PurchaseMethod
{   
    All = ~0,
    None =  0,
    Cash =  1,
    Check =  2,
    CreditCard =  4
}

私はそれを見て少し驚いたので、コンパイルしようとしましたが、うまくいきました...しかし、それが何を意味するのか/何をするのかはまだわかりません。何か助けて??

4

10 に答える 10

138

~ は単項の 1 の補数演算子です。オペランドのビットを反転します。

~0 = 0xFFFFFFFF = -1

2 の補数演算では、~x == -x-1

~ 演算子は、Objective-C/C++/C#/Java/Javascript を含む、C から構文を借用したほとんどすべての言語で見つけることができます。

于 2008-12-22T21:38:17.140 に答える
60

私はそれを思うだろう:

[Flags]
public enum PurchaseMethod
{
    None = 0,
    Cash = 1,
    Check = 2,
    CreditCard = 4,
    All = Cash | Check | CreditCard
 }

もう少し明確になります。

于 2008-12-22T21:42:59.987 に答える
23
public enum PurchaseMethod
{   
    All = ~0, // all bits of All are 1. the ~ operator just inverts bits
    None =  0,
    Cash =  1,
    Check =  2,
    CreditCard =  4
}

C# の 2 の補数により~0 == -1、バイナリ表現ですべてのビットが 1 である数。

于 2008-12-22T21:37:42.587 に答える
17

そのより良い

All = Cash | Check | CreditCard

後で別のメソッドを追加する場合は、次のように言ってください。

PayPal = 8 ,

チルダ-すべては既に完了していますが、すべての行を他の行に変更する必要があります。そのため、後でエラーが発生しにくくなります。

よろしく

于 2008-12-22T22:38:03.887 に答える
11

使用時の注意点

All = Cash | Check | CreditCard

すべての値を含みながらすべてと等しくない別の値 (-1) に評価され、Cash | Check | CreditCard評価されないという追加の利点があります。Allたとえば、UI で 3 つのチェック ボックスを使用する場合

[] Cash
[] Check
[] CreditCard

それらの値を合計し、ユーザーがそれらをすべて選択するとAll、結果の列挙に表示されます。

于 2008-12-22T23:00:36.493 に答える
9

この質問に光を当てた人のために、簡単な~例を紹介します。ペイント メソッドの実装からの次のスニペットは、この Mono ドキュメント~で詳しく説明されているように、非常に効果的に使用されています。

PaintCells (clipBounds, 
    DataGridViewPaintParts.All & ~DataGridViewPaintParts.SelectionBackground);

演算子がない~と、コードはおそらく次のようになります。

PaintCells (clipBounds, DataGridViewPaintParts.Background 
    | DataGridViewPaintParts.Border
    | DataGridViewPaintParts.ContentBackground
    | DataGridViewPaintParts.ContentForeground
    | DataGridViewPaintParts.ErrorIcon
    | DataGridViewPaintParts.Focus);

...列挙は次のようになるためです。

public enum DataGridViewPaintParts
{
    None = 0,
    Background = 1,
    Border = 2,
    ContentBackground = 4,
    ContentForeground = 8,
    ErrorIcon = 16,
    Focus = 32,
    SelectionBackground = 64,
    All = 127 // which is equal to Background | Border | ... | Focus
}

この列挙型が Sean Bright の回答と似ていることに気付きましたか?

私にとって最も重要なこと~は、列挙型の演算子が通常のコード行と同じであることです。

于 2011-11-04T22:01:01.767 に答える
5

これは補数演算子です。これは、ビット演算子についてよく参照する記事です。

http://www.blackwasp.co.uk/CSharpLogicalBitwiseOps.aspx

また、msdnは列挙型の記事でそれを使用しており、より適切に使用できることを示しています

http://msdn.microsoft.com/en-us/library/cc138362.aspx

于 2008-12-22T21:42:52.653 に答える
1

私が個人的に使用する代替手段は、@Sean Brightの答えと同じことを行いますが、私には良く見えますが、これは次のとおりです。

[Flags]
public enum PurchaseMethod
{
    None = 0,
    Cash = 1,
    Check = 2,
    CreditCard = 4,
    PayPal = 8,
    BitCoin = 16,
    All = Cash + Check + CreditCard + PayPal + BitCoin
}

すべて 2 の累乗であるこれらの数値の 2 進数の性質が、次の主張をどのように真にするかに注目してください(a + b + c) == (a | b | c)。そして、私見、+より良く見えます。

于 2013-02-21T03:05:03.867 に答える