[解決済み] この2行は同じものなのでしょうか?
2023-07-06 22:43:03
質問
この2つの行に違いはあるのでしょうか?
MyName = (s.MyName == null) ? string.Empty : s.MyName
または
MyName = s.MyName ?? string.Empty
どのように解決するのですか?
UPDATE: このトピックについて、より深く掘り下げたブログ記事を書きました。 http://www.codeducky.org/properties-fields-and-methods-oh-my/
一般に、これらは同じ結果を返します。 しかし、以下のような場合、顕著な違いを経験することになります。
MyName
がプロパティであるため
MyName
ゲッターは最初の例では2回実行され、2番目の例では1回だけ実行されるからです。
を実行することによるパフォーマンスの違いを経験するかもしれません。
MyName
を2回実行することによるパフォーマンスの違いを感じるかもしれません。
string MyName
{
get
{
Thread.Sleep(10000);
return "HELLO";
}
}
を実行すると、異なる結果が得られるかもしれません。
MyName
を二回実行すると
MyName
がステートフルである場合、2回になります。
private bool _MyNameHasBeenRead = false;
string MyName
{
get
{
if(_MyNameHasBeenRead)
throw new Exception("Can't read MyName twice");
_MyNameHasBeenRead = true;
Thread.Sleep(10000);
return "HELLO";
}
}
を実行すると、異なる結果が得られるかもしれません。
MyName
を二回実行すると
MyName
は別のスレッドで変更することができます。
void ChangeMyNameAsync()
{
//MyName set to null in another thread which makes it
//possible for the first example to return null
Task.Run(() => this.MyName = null);
}
string MyName { get; set; }
実際のコードをコンパイルしてみると、以下のようになります。まず、3項式の部分です。
IL_0007: ldloc.0 // s
IL_0008: callvirt s.get_MyName <-- first call
IL_000D: brfalse.s IL_0017
IL_000F: ldloc.0 // s
IL_0010: callvirt s.get_MyName <-- second call
IL_0015: br.s IL_001C
IL_0017: ldsfld System.String.Empty
IL_001C: call set_MyName
で、これがヌルコアレシング演算子を使った作品です。
IL_0007: ldloc.0 // s
IL_0008: callvirt s.get_MyName <-- only call
IL_000D: dup
IL_000E: brtrue.s IL_0016
IL_0010: pop
IL_0011: ldsfld System.String.Empty
IL_0016: call s.set_MyName
ご覧の通り、三項演算子のコンパイル済みコードはプロパティ値を取得するために2回の呼び出しを行いますが、ヌルコアレスティング演算子は1回しか行いません。
関連
-
[解決済み】C#でクエスチョンマークを2つ並べるとどんな意味になるのか?
-
[解決済み】トランスポート接続からデータを読み取れない:既存の接続は、リモートホストによって強制的に閉じられました。
-
[解決済み] C#のStringとstringの違いは何ですか?
-
[解決済み] C#の正しいバージョン番号を教えてください。
-
[解決済み] AddTransient、AddScoped、AddSingleton サービスの相違点
-
[解決済み] C#のconstとreadonlyの違いは何ですか?
-
[解決済み] 2つの日付の差(日数)を計算する?
-
[解決済み] SelectとSelectManyの違い
-
[解決済み] IEnumerable<T> と IQueryable<T> を比較する。
-
[解決済み] キーワード「ref」と「out」の違いは何ですか?
最新
-
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 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】スクリプトクラスが見つからないので、スクリプトコンポーネントを追加できない?
-
[解決済み】C#におけるtypedefの等価性
-
[解決済み] 保護レベルによりアクセス不能になりました。
-
[解決済み] 'SubSonic.Schema .DatabaseColumn' 型のオブジェクトをシリアライズする際に、循環参照が検出されました。
-
[解決済み】プロジェクトビルド時のエラー。エディタでスクリプトにコンパイルエラーがあるため、Playerのビルドにエラーが発生する
-
[解決済み】値が期待した範囲に収まらない
-
[解決済み】EF 5 Enable-Migrations : アセンブリにコンテキストタイプが見つかりませんでした
-
[解決済み】ユーザー設定値を別のユーザー設定値で設定する
-
[解決済み】データが存在しないのに読み込もうとする試みが無効である
-
[解決済み】スレッド終了またはアプリケーションの要求により、I/O操作が中断されました。