[解決済み] C#で演算子==はジェネリック型に適用できない?
質問
のドキュメントによると
==
演算子を
MSDN
,
定義済みの値の型については 等号演算子 (==) は、以下の場合に真を返します。 オペランドの値が等しいこと。 それ以外は偽。参照型 は、文字列以外の場合、== が真を返します。 その2つのオペランドは、同じ オブジェクトを作成します。文字列型の場合、== は文字列の値を比較する。 ユーザー定義の値型は,オーバーロードすることができる。 演算子(演算子参照)を使用します。また ユーザー定義の参照型ですが は、デフォルトで==のように動作します。 定義済みと定義済みの両方について、上記の ユーザー定義参照型
では、なぜこのコード・スニペットはコンパイルに失敗するのでしょうか?
bool Compare<T>(T x, T y) { return x == y; }
エラーが表示される
演算子 '==' は、型 'T' および 'T' のオペランドに適用できません。
. 私が理解している限りでは
==
演算子はすべてのタイプであらかじめ定義されているのですか?
編集してください。 みなさん、ありがとうございます。参照型のみに関する記述であることに最初気がつきませんでした。また、ビット単位の比較はすべての値型に対して提供されていると考えていましたが、これは今となっては ではなく が正しいです。
しかし、参照型を使用している場合、このように
==
演算子は定義済みの参照比較を使うのでしょうか、それとも型が定義していればオーバーロードされた演算子を使うのでしょうか?
編集2:
試行錯誤の末に
==
演算子は、制限のない一般的な型を使用する場合、定義済みの参照比較を使用します。実際には、コンパイラは制限された型の引数に対して最も良い方法を使用しますが、それ以上は調べません。たとえば、次のコードは常に
true
の場合であっても
Test.test<B>(new B(), new B())
が呼び出されます。
class A { public static bool operator==(A x, A y) { return true; } }
class B : A { public static bool operator==(B x, B y) { return false; } }
class Test { void test<T>(T a, T b) where T : A { Console.WriteLine(a == b); } }
解決方法は?
"...デフォルトでは、定義済みおよびユーザー定義の両方の参照タイプについて、==上記のように動作します。
T型は必ずしも参照型ではないので、コンパイラはその仮定をすることができません。
しかし、これはより明示的であるため、コンパイルされます。
bool Compare<T>(T x, T y) where T : class
{
return x == y;
}
しかし、参照型を使用している場合、==演算子は定義済みの参照比較を使用するのでしょうか、それとも型が定義されている場合はオーバーロード版の演算子を使用するのでしょうか。
Genericsの==はオーバーロード版を使用すると思っていましたが、次のテストではそうでないことが証明されています。 興味深いですね。なぜなのか、ぜひ知りたいです もし知っている人がいたら教えてください。
namespace TestProject
{
class Program
{
static void Main(string[] args)
{
Test a = new Test();
Test b = new Test();
Console.WriteLine("Inline:");
bool x = a == b;
Console.WriteLine("Generic:");
Compare<Test>(a, b);
}
static bool Compare<T>(T x, T y) where T : class
{
return x == y;
}
}
class Test
{
public static bool operator ==(Test a, Test b)
{
Console.WriteLine("Overloaded == called");
return a.Equals(b);
}
public static bool operator !=(Test a, Test b)
{
Console.WriteLine("Overloaded != called");
return a.Equals(b);
}
}
}
出力
インラインで オーバーロード == 呼ばれる
一般的なものです。
任意のキーを押して続ける . . .
フォローアップ2
ただし、比較メソッドを
static bool Compare<T>(T x, T y) where T : Test
{
return x == y;
}
は、オーバーロードされた == 演算子が呼び出されます。 型を指定しないと、( ここで というのは、コンパイラはオーバーロードされた演算子を使うべきであると推論できないからだ...たとえ型を指定しなくても、コンパイラはその判断をするのに十分な情報を持っていると思うのだが。
関連
-
[解決済み】指定されたキャストが有効でない?
-
[解決済み】MetadataException: 指定されたメタデータ・リソースをロードできない
-
[解決済み] とは何ですか! (not not)演算子とは何ですか?
-
[解決済み] C言語では「?」演算子は何をするのですか?
-
[解決済み] JavaScriptに「NULL合体」演算子はありますか?
-
[解決済み】C/C++の"-->"演算子とは何ですか?
-
[解決済み】JavaScriptの比較では、どちらの等号演算子(== vs ===)を使うべきですか?
-
[解決済み】TをEnumに拘束するGenericメソッドの作成
-
[解決済み】Pythonに三項条件演算子はありますか?
-
[解決済み] リファレンス - このシンボルはPHPで何を意味するのですか?
最新
-
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 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】「未割り当てのローカル変数を使用」とはどういう意味ですか?
-
[解決済み】指定されたキャストが有効でない?
-
[解決済み】プログラム実行中に1秒待つ
-
[解決済み] [Entity Framework 4.1でエンティティに関連オブジェクトを追加する際に、エンティティオブジェクトをIEntityChangeTracker.の複数のインスタンスから参照できない。
-
[解決済み】C# - パスに不正な文字がある場合
-
[解決済み] UnityでOnCollisionEnterが呼ばれない
-
[解決済み】Linq 構文 - 複数列の選択
-
[解決済み】WebResource.axdとは何ですか?
-
[解決済み】名前 'ViewBag' が現在のコンテキストに存在しない - Visual Studio 2015
-
[解決済み】Nullableオブジェクトは値を持たなければならない?