[解決済み] C#の"!="と "is not "は違うのですか?
質問
これは何ですか?
if(x != y)
{
}
とは異なります。
if (x is not y)
{
}
それとも、2つの条件に違いはないのでしょうか?
どのように解決するのですか?
比較表です。
!=
is not
本来の目的
値の不等号
否定的な
パターンマッチ
値の不等式を行うことができる
可能
はい
否定的なパターンマッチを行うことができる
いいえ
はい
呼び出すことができます
implicit
演算子を使用することができます。
はい
いいえ
呼び出すことができます
implicit
演算子を使用することができます。
はい
はい
1
自身の演算子である
はい
いいえ
2
オーバーロード可能
はい
いいえ
より
C# 1.0
C# 9.0
3
値型ヌル比較ブランチ
エリジョン
4
はい
いいえ
<サブ
[要出典] (Citation needed)
5
不可能な比較
エラー
警告
左オペランド
任意の式
任意の表現
右オペランド
任意の式
定数式のみ
<any-expr> != <any-expr>
<any-expr> is [not] <const-expr> [or|and <const-expr>]*
その他
よくある例です。
!=
is not
nullではない
x != null
x is not null
値の不等号の例
x != 'a'
x is not 'a'
ランタイムタイプの(誤)一致
x.GetType() != typeof(Char)
x is not Char
7
SQL
x NOT IN ( 1, 2, 3 )
x != 1 && x != 2 && x != 3
x is not 1 or 2 or 3
OPの質問に答えるために 直接かつ具体的に :
if( x != y ) { }
// vs:
if( x is not y ) { }
-
もし
x
が積分値型である場合(例えばint
/Int32
) とy
はconst-expression
(である(例えばconst int y = 123;
) なら いいえ の場合、違いはなく、両方のステートメントで同じ .NET MSIL バイトコードが生成されます (コンパイラの最適化を有効にしている場合と無効にしている場合の両方)。 -
もし
y
が(値名ではなく)型名である場合、そこに は という違いがあります。if
ステートメントは無効でコンパイルできません。if( x is not y )
ステートメントは 型パターン の代わりにマッチします。 定数パターン にマッチします。
脚注です。
-
"定型パターン" : "入力値がオープン型でない場合、定数式はマッチした式の型に暗黙的に変換されます" 。
-
x is not null
は、より類推しやすいように!(x == null)
よりもx != null
. -
C# 7.0 では、いくつかの限定された形式の constant-pattern マッチングが導入され、C# 8.0ではさらに拡張されましたが、C# 9.0になってから
not
という否定演算子(あるいは修飾子)が追加されたのはC# 9.0です。 -
のように、非制約のジェネリックメソッドが与えられる。
void Foo<T>( T x ) { if( x == null ) { DoSomething(); } DoSomethingElse(); }
...JITが上記のジェネリックメソッドをインスタンス化するとき(すなわち。 単形化 ) の場合
T
が値型(struct
) の場合、全体のif( x == null ) { DoSomething(); }
ステートメント ( とそのブロックの内容 ) はJITコンパイラによって削除されます ("elision")。これは、値tupeは決してnull
. これは、最適化コンパイラーによって処理されることを期待しますが、.NET JIT はこの特定のシナリオのために特別にハードコードされたルールを持っていると私は理解しています。-
不思議なことに、C# の以前のバージョン (7.0 など) では、エリジョン ルールは
==
と!=
演算子ではなくis
演算子ではありませんのでif( x == null ) { DoSomething(); }
は消去されますが、ステートメントif( x is null ) { DoSometing(); }
は ではなく でない限り、コンパイラエラーが発生します。T
に拘束されない限り、コンパイラエラーが発生します。where T : class
. C# 8.0 からは、制約のない一般的な型に対して許可されるようになったようです。
-
不思議なことに、C# の以前のバージョン (7.0 など) では、エリジョン ルールは
-
驚いたことに、これに関する権威あるソースは見つかりませんでした (公開されている C# 仕様は現在ではかなり古くなっているためです。
csc
のソース コードを調べてみたいとは思いません)。- C# コンパイラと JIT のどちらも不可能分岐を適用しない場合は 定数パターン 式がある場合、私は を考える は、単に現状では難しいからかもしれません。
-
なお 定数式 を意味するものではありません。 リテラル式 を意味するものではありません。
const
の値を使うことができます。enum
メンバなど、すべての部分式が同じであれば、自明でない生の式でも 定数式 .-
というケースがあるのか気になるところです。
static readonly
フィールドが使えるかどうかが気になるところですが。
-
というケースがあるのか気になるところです。
-
の場合は
typeof(X) != y.GetType()
の場合、この式はtrue
とするとX
から派生したものです。y
の型から派生したものである(両者は異なる型であるため)、しかしx is not Y
は実際にはfalse
というのはx
はY
(なぜならx
のサブクラスのインスタンスであるためY
). を使う場合Type
を使う場合は、次のようにするのがよいでしょう。typeof(X).IsSubclassOf(y.GetType())
とか、もっと緩いy.GetType().IsAssignableFrom(typeof(X))
.-
ただし、この場合は
Char
は構造体なので、型階層に参加することはできません。!x.IsSubclassOf(typeof(Char))
を使うのは馬鹿馬鹿しいだけです。
-
ただし、この場合は
関連
-
[解決済み】"The ConnectionString property has not been initialized "を修正する方法
-
[解決済み] JavaScriptで "use strict "は何をするのか、その根拠は?
-
[解決済み] C#のStringとstringの違いは何ですか?
-
[解決済み] パラメータに**(ダブルスター/アスタリスク)、*(スター/アスタリスク)がありますが、これはどういう意味ですか?
-
[解決済み] C#のconstとreadonlyの違いは何ですか?
-
[解決済み] 2つの日付の差(日数)を計算する?
-
[解決済み] SelectとSelectManyの違い
-
[解決済み] .の違いは何ですか?(ドット)と$(ドルマーク)の違いは何ですか?
-
[解決済み] Bashのシングルクォートとダブルクォートの違い
-
[解決済み】大文字・小文字を区別しない「Contains(string)
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] [Solved] 1つ以上のエンティティで検証に失敗しました。詳細は'EntityValidationErrors'プロパティを参照してください [重複]。
-
[解決済み】プログラム実行中に1秒待つ
-
[解決済み】Ajax処理で「無効なJSONプリミティブ」と表示される件
-
[解決済み】プロジェクトビルド時のエラー。エディタでスクリプトにコンパイルエラーがあるため、Playerのビルドにエラーが発生する
-
[解決済み】バックスラッシュを含むパス文字列のエスケープシーケンスが認識されない件
-
[解決済み】取り消せないメンバはメソッドのように使えない?
-
[解決済み】なぜこのコードはInvalidOperationExceptionを投げるのですか?
-
[解決済み】"指定されたパスのフォーマットはサポートされていません。"
-
[解決済み】ユーザー設定値を別のユーザー設定値で設定する
-
[解決済み】IEEE754のNaN値に対して、すべての比較がfalseを返す根拠は何ですか?