何が"ベストプラクティス"とを比較するための二つのインスタンスの参考にす

StackOverflow https://stackoverflow.com/questions/104158

質問

またこの最近では、これまで私は幸せをオーバーの平等のオペレーター(==)および/または Equals するための方法論がつ参照型を実際に含まれる同 データ (異なる二つのインスタンスに見えるが生じることがあります

合わせてもらっていますが、自動化試験との比較参考になるデータに対する返す。

を眺めながらの世 符号化の標準ガイドラインにMSDN 私た このよう勧告します。今理解してい なぜ 第条は"これは同じではありません インスタンス がないという疑問に対する回答

  1. には、どうするのがベストなの比較に対すか?
  2. べき実施していま IComparable?してくれてありがとうございますも見ることにより、この留保される値型のみ)。
  3. あェわからないですか?
  4. べきでしょロール独自の?!

多くん^_^

更新

ようになった誤読のドキュメント(メンバーで長い間日)をオーバー Equals はう..

を実装中の場合は参照 種類うことを検討すべき重 メソッドは、Equalsメソッドとの関連を参照型 の場合タイプのようなベースタイプ など、文字列、BigNumber, います。最参照型 な過負荷に 平等 オペレーター, も 場合にはEquals.しかし、 を実装中の場合は参照 タイプにない価値 意味論などの複素数 タイプ、オーバーライドの平等 オペレーター

役に立ちましたか?

解決

そのような符号化クライアントまで、フルのC#るという方法でEqualsるクラスを実施し、比較したいのは、二つのオブジェクトが実際に使用その他の指標により"はこれら二つのポインタがオブジェクトが扱うだけで、ポイント)同じメモリをダウンロードで".

沢山しゃべらないと行けないサンプルコード こちらの:

class TwoDPoint : System.Object
{
    public readonly int x, y;

    public TwoDPoint(int x, int y)  //constructor
    {
        this.x = x;
        this.y = y;
    }

    public override bool Equals(System.Object obj)
    {
        // If parameter is null return false.
        if (obj == null)
        {
            return false;
        }

        // If parameter cannot be cast to Point return false.
        TwoDPoint p = obj as TwoDPoint;
        if ((System.Object)p == null)
        {
            return false;
        }

        // Return true if the fields match:
        return (x == p.x) && (y == p.y);
    }

    public bool Equals(TwoDPoint p)
    {
        // If parameter is null return false:
        if ((object)p == null)
        {
            return false;
        }

        // Return true if the fields match:
        return (x == p.x) && (y == p.y);
    }

    public override int GetHashCode()
    {
        return x ^ y;
    }
}

Javaは非常に類似のメカニズム。の equals() 方法は オブジェクト クラスのクラスが過負荷になりましたい場合はこのタイプの可能です。

その理由を過積載'=='ができるのは悪いことのためのオブジェクトは、通常使いができるように"はこれらの同じポインタ"。これらは、通常、信頼、インスタンスを挿入しながら、要素をリストアップが複製は許可されませんが、一部の枠組みのものが動作しない場合はこのオペレータが過負荷状態で運転される非定します。

他のヒント

の実施に平等です。純正しく、効率的 なしコードの重複 はつらいです。具体的には、参照の型と値の意味につ 不変な種類を取り扱うequvialenceとして平等きの実施 System.IEquatable<T> インタ, すで実装すべき全ての業務Equals, GetHashCode==, !=).

一例として、"わらびもち"をここで実装するクラスで価値の平等:

class Point : IEquatable<Point> {
    public int X { get; }
    public int Y { get; }

    public Point(int x = 0, int y = 0) { X = x; Y = y; }

    public bool Equals(Point other) {
        if (other is null) return false;
        return X.Equals(その他。X)&&Y.Equals(その他。Y);
    }

    public override bool Equals(object obj) => Equals(obj as Point);

    public static bool operator ==(Point lhs, Point rhs) => object.Equals(lhs, rhs);

    public static bool operator !=(Point lhs, Point rhs) => ! (lhs == rhs);

    public override int GetHashCode() => X.GetHashCode()^Y.GetHashCode();
}

の可動部を上記のコードのboldedパーツ:第二線 Equals(Point other)GetHashCode() 方法。その他のコードの変更はありません。

参考いないクラスを表す不変の価値観を導入していません事業者の ==!=.代わりに使用しますデフォルトの意味であるオブジェクトを比較します。

このコード 意図的に 競争力の強化に取り組ものオブジェクトの派生クラスタイプです。しばしば、このような望ましいので平等の基底クラスと導出クラスでは定義されています。残念ながら、.純とのコーディングのガイドラインはまだ不透明です。このコードが簡単に、ios、androidとmac用にc#の作成-掲載 他の答え, は、以下に望ましくない行動のような場合で Equals(object x)Equals(SecurableResourcePermission x) この場合とは異なります。

変更するために、この行動は、追加のタイプチェックが挿入されるのを強く型 Equals 上記方法:

public bool Equals(Point other) {
    if (other is null) return false;
    if (other.GetType() != GetType()) return false;
    return X.Equals(その他。X)&&Y.Equals(その他。Y);
}

以下において一括していただける場合の実施IEquatableとの理由から、様々なMSDNの文書は頁とします。


概要

  • 場試験のための価値の平等を希望などを利用の場合オブジェコレクション)を実施する上でのIEquatableインタフェースのオーバーライドオブジェクトです。Equals、およびGetHashCodeごクラスです。
  • テストの際の参考と等しいかどうかは、ご希望のものを使用できる演算子==,オペレーター!= や オブジェクトです。ReferenceEquals.
  • きみのオーバーライドオペレーター==およびオペレーター!= のための ValueTypes と不変なので参考です。

正当化

IEquatable

のシステム。IEquatableインタフェースの比較で使われている二つのインスタンスのオブジェクトを進めていきます。の物体との比較に基づくロジックを実施します。の比較結果を示すboolean値。trueの場合、チェ合物が異なります。これに対し、システム。IComparableインタフェースを返しの整数をどのように行うかを示すオブジェクトの値が異なります。

のIEquatableタを宣言方法が必要なオーバーライドになります。のEqualsメソッドの実装を行う際比較の場合にtrueを返しオブジェクトの値が等しい場合はfalseています。のGetHashCode方法を返す独自のハッシュ値が一意に識別するために使用され同一のオブジェクトを含むの値が異なります。タイプのハッシュに使用するアルゴリズムは実装固有のものです。

IEquatable.Equalsメソッド

  • まぼすおそれのある機器、装置IEquatable用オブジェクトの取り扱う可能性を保持する配列、あるいは一般です。
  • を実装する場合IEquatableるべきものオーバーライドベースのクラスの実装オブジェクトです。Equals(Object)、およびGetHashCodeその挙動と矛盾しないことを確認した。にIEquatable.Equalsメソッド

ガイドラインをオーバー Equals()は、演算子==(C#プログラミングガイド)

  • x.Equals(x)はtrueを返します。
  • x.Equals(y)が返す値と同じです。Equals(x)
  • if(x.Equals(y)&&y.Equals(z))はtrueを返し、x.Equals(z)はtrueを返します。
  • 歴代のメソッドの呼び出し。Equals(y)と同じ値を返し、オブジェによって参照されるx、yは変更されません。
  • x.Equals(null)はfalseを返します(ための非null値の種類です。詳細については、 Nullable種(C#プログラミングガイド).)
  • の実施のEqualsなげることができます。
  • そのクラスがEqualsをオーバーライドもオーバーライドオブジェクトです。GetHashCode.
  • であることをお勧めを実施するほか、Equals(object)、任意のクラスを実施しますEquals(タイプ)のための独自の型を高めます。

デフォルトでは、演算子==試験のための基準平等により決定するかどうかにつ参考文献を示すのと同じオブジェクトです。 そのため、参照型のない実演算子==を高めることができる非常によ可能です。時の型は変更不可能なので、データに含まれるインスタンスの変更はできません、過積載運==値を比較する平等な参考平等ができるので便利で、変更不能なオブジェ、それと同じ長していくと、同じ値を表示します。 ないオーバーライドオペレーター==非変更できます。

  • 過負荷オペレーター==実装なげることができます。
  • タが過負荷になオペレーター==べきものオペレーターの過負荷!=.

==演算子とC#のサンプルソースコードを参照)

  • 定義済みの値タイプには、平等のオペレーター(==)の場合にtrueを返しま価値観のオペランドが等しいかどうかを判定します。.
  • 参考種類以外の文字列==trueを返す場合、その二つのオペランドが参照が同じオブジェクトです。
  • 文字列のタイプ、==値とを比較し、文字列です。
  • 場試験のためのnull==を使用して比較内のオペレーター==オーバーライドでくださいをご利用のベースオブジェクトのクラス。ない場合は、無限再帰が発生しますよstackoverflow.

オブジェクトです。Equals(Object)

の場合プログラミング言語対応オペレーターの過負荷とき過負荷の平等のオペレーターの指定されたタイプ、型はオーバーライドメソッドは、Equalsメソッドとの関連.に、そのような実装メソッドは、Equalsメソッドとの関連を返す必要があり同様の結果としてこれらの研究を推進オペレーター

以下のガイドラインを実装するための 値型:

  • 検討をオーバー Equals得増加の性能を発揮できるようになっており、デフォルトの実施等にValueType.
  • まEqualsの言語対応オペレーターの過負荷、過負荷の平等のオペレーターのお値タイプです。

以下のガイドラインを実装するための 参照型:

  • 検討Equalsをオーバー、参照型の場合は意味のタイプに基づき、その型を表す値とします。
  • もつ参照型は過負荷の平等のオペレーターでも、Equals.ただし、合格した場合の実施参考にタイプしたものとして価値の意味などの複素数型は、オーバーライドは、同等演算子です。

追加Gotchas

この記事で推奨対策の平等のオペレーター(参考)に逆らうのではなくEqualsをオーバー.まEquals内のオブジェクト(参照値)の場合の平等の確認までの平均以上のものを参考確認をしています。したい場合は、最新のインスタレーションも可能ですの実施 IEquatable (汎用集).う場合の実施IEquatableしるべきものオーバーライドは、equalsのIEquatable欄の国:

を実装する場合IEquatable<T>るべきものオーバーライドベースのクラスの実装オブジェクトです。Equals(Object)、およびGetHashCodeその挙動と矛盾しないことを確認した。にIEquatable<T>.Equals方法です。う場合のオーバーライドオブジェクトです。Equals(Object)、おのメソッドの実装が呼び出して電話静Equals(システム。オブジェクトのシステム。オブジェクト)メソッド。これにより、すべてのメソッドの呼び出しのEqualsメソッドの戻り値の一貫した。

についてから実施するべきであるEqualsおよび/またはこれらの研究を推進オペレーター:

から 実行メソッドは、Equalsメソッドとの関連

もつ参照型は過負荷の平等のオペレーターでも、Equals.

から ガイドラインの実施のためのEqualsおよびこれらの研究を推進オペレーター(==)

オーバーライドは、Equalsメソッドは必を実装するこれらの研究を推進オペレーター(==)させることができるようになり、も同じです。

これだけは言うにする必要がありEqualsき実施する平等なります。とまりん ない と言うのに必要なものをオーバーライドオペレーターの平等ときはEquals.

複雑なオブジェクトにすることを特定の比較を実施IComparable義の比較の比較方法が実装されます。

例として"車両"オブジェクトのみがなされない場合は、登録番号を使用していますを比較するための見返される値試験は、いままです。

を使うのか簡単に、ios、androidとmac用にc#自動的にすることとしています。例えば、autocreatedこの参照型:

public override bool Equals(object obj)
{
    if (ReferenceEquals(null, obj)) return false;
    if (ReferenceEquals(this, obj)) return true;
    return obj.GetType() == typeof(SecurableResourcePermission) && Equals((SecurableResourcePermission)obj);
}

public bool Equals(SecurableResourcePermission obj)
{
    if (ReferenceEquals(null, obj)) return false;
    if (ReferenceEquals(this, obj)) return true;
    return obj.ResourceUid == ResourceUid && Equals(obj.ActionCode, ActionCode) && Equals(obj.AllowDeny, AllowDeny);
}

public override int GetHashCode()
{
    unchecked
    {
        int result = (int)ResourceUid;
        result = (result * 397) ^ (ActionCode != null ? ActionCode.GetHashCode() : 0);
        result = (result * 397) ^ AllowDeny.GetHashCode();
        return result;
    }
}

したい場合にオーバーライド == だrefチェックを利用することができ Object.ReferenceEquals.

Microsoftが変更にその調整、または少なくともいう相反する情報は過負荷の平等なります。このよう Microsoft第 題方法:定義価値の平等のためのタイプ:

"第==および!= 事業者に使用できるクラスの場合でもクラスでは過負荷します。しかし、デフォルトの行動を参考に平等にチェック。クラスでた場合、過負荷のメソッドは、Equalsメソッドとの関連、過負荷、==および!= 事業者が、その必要はありません。"

によるエリック-Lippert氏 答え うに聞いて 最小限のコードは、同等クライアントまで、フルのC# -その使命を果たすために

"の危険性にせまるお==演算子が定義されている基準等によるデフォルトです。が容易に状況が過Equalsメソッドは値の平等と==does参考平等、そして偶発的に使用基準等には関等しいことに価値の平等なものとする。このエラーが発生しやすいでいくスポットによる人間コードです。

なお、トイレットペーパーの前というのは静的解析アルゴリズムを統計的に検出す状況ではなかったので、不良率のつのインスタンス百万ド全codebasesした。を考えた場合でcodebasesたどこかのオーバーライド等の欠陥率も大幅に高!

また、コストvsのリスクに対するすでに実装IComparableを執筆すべての事業者には自明であるがワンライナーなバグをすることはありません。で一番安いコードだけは今す。が変更されていない場合は、選択肢との間で固定費の筆記試験は、十数の小さな手法vs限のコストの固定見bugが参照等を行うことが、おいしく、価値の平等、知っているか。"

きます。NETフレームワークまで今までにない使用==以!= 任意のタイプにします。しかし、危険はどうなるだろうか、という人がいます。そのため、このクラスでは、第3者というもの==および!= います。場合にのみ使用されることにより、グループは、今の実行==および!= います。

私だけの実施を <, <=,>、>=演算子の場合IComparableを実装しました。IComparableをとるべき実施する場合には必要な支援を注文様が選別または使用順汎用コンテナのようなSortedSet.

である場合には、当社グループや当社の方針を今までになかの実行==および!= オペレーターというもちろん追手段の確保にも努めています。場合はそのような政策がそうにって保管しなければならないとQ/Aコード解析ツールがフラグを立てますの発生==および!= 事業者の場合を参照。

と思いくなど簡単なものをチェックオブジェクトの平等を是正するのが少々難です。純ります。

構造体

1)実施 IEquatable<T>.でパフォーマンス向上を図動きが一段と明確になっている。

2)すると自分の Equals 現在、オーバーライド GetHashCode, ととの整合性も確保するために各種の同一性チェックのオーバーライド object.Equals しています。

3)過負荷 ==!= 事業者が必要な宗教的に行ってコンパイラの警告を表示まが意図せずに相当structうと == または !=, が良いとの整合性も確保するために Equals ます。

public struct Entity : IEquatable<Entity>
{
    public bool Equals(Entity other)
    {
        throw new NotImplementedException("Your equality check here...");
    }

    public override bool Equals(object obj)
    {
        if (obj == null || !(obj is Entity))
            return false;

        return Equals((Entity)obj);
    }

    public static bool operator ==(Entity e1, Entity e2)
    {
        return e1.Equals(e2);
    }

    public static bool operator !=(Entity e1, Entity e2)
    {
        return !(e1 == e2);
    }

    public override int GetHashCode()
    {
        throw new NotImplementedException("Your lightweight hashing algorithm, consistent with Equals method, here...");
    }
}

クラス

MS:

もつ参照型は過負荷の平等のオペレーターでも、Equals.

== 感のような価値の平等、という統語砂糖 Equals 方法。書く a == b のではなく直感的に上書き a.Equals(b).稀にする必要がありまめにチェック基準を進めていきます。抽象レベルを扱う論理的表現な物理的なこというのは大きく変わってしまうことがありチェックするのような異なるセマンティクス ==Equals できるので混乱している。と思うはずで == 価値の平等と Equals 参照(や名様 IsSameAs)平等。 思い出いっぱいなMSの指針を真剣にこなしていないので自然がい過負荷 == がないとも呼ばれている。 ことになるとは異なりはオノ-dbg Equals または GetHashCode を噛むことができ、ための枠組みを使用しませんの == この場合のみお一人歩きして使用します。の付いた得ら ない過負荷 ==!= の一貫性とデザイン全体の枠組みを超えほどの場所に位置してい制御す。ことになるのも大きなもの くんまったら、それを守ってほしい.

と参照セマンティクス(変更可能なオブジェクト)

1)オーバーライド EqualsGetHashCode.

2)実施 IEquatable<T> んなでコミュニケーションを取り合います。

public class Entity : IEquatable<Entity>
{
    public bool Equals(Entity other)
    {
        if (ReferenceEquals(this, other))
            return true;

        if (ReferenceEquals(null, other))
            return false;

        //if your below implementation will involve objects of derived classes, then do a 
        //GetType == other.GetType comparison
        throw new NotImplementedException("Your equality check here...");
    }

    public override bool Equals(object obj)
    {
        return Equals(obj as Entity);
    }

    public override int GetHashCode()
    {
        throw new NotImplementedException("Your lightweight hashing algorithm, consistent with Equals method, here...");
    }
}

価値意味論(変更不能なオブジェクト)

このトリッキーです。で容易にすぐればなケア..

1)オーバーライド EqualsGetHashCode.

2)過負荷 ==!= 合わせ Equals. 確ードを動作させることができnull.

2)実施 IEquatable<T> んなでコミュニケーションを取り合います。

public class Entity : IEquatable<Entity>
{
    public bool Equals(Entity other)
    {
        if (ReferenceEquals(this, other))
            return true;

        if (ReferenceEquals(null, other))
            return false;

        //if your below implementation will involve objects of derived classes, then do a 
        //GetType == other.GetType comparison
        throw new NotImplementedException("Your equality check here...");
    }

    public override bool Equals(object obj)
    {
        return Equals(obj as Entity);
    }

    public static bool operator ==(Entity e1, Entity e2)
    {
        if (ReferenceEquals(e1, null))
            return ReferenceEquals(e2, null);

        return e1.Equals(e2);
    }

    public static bool operator !=(Entity e1, Entity e2)
    {
        return !(e1 == e2);
    }

    public override int GetHashCode()
    {
        throw new NotImplementedException("Your lightweight hashing algorithm, consistent with Equals method, here...");
    }
}

特別な注意を払うべきである運賃の場合のクラスを継承し、その場合する場合ベースのclassオブジェクトが自動車メーカーをはじめとする派生クラスオブジェクトです。理想的には、いない場合は物由来のクラスを使用するための平等を確認し、基底クラスのインスタンス自動車メーカーをはじめとする派生クラスのインスタンスなどの必要がないチェック Type 平等汎用 Equals の基底クラスです。

一般的な複製のコードです。私が一般的抽象基底クラスIEqualizable<T> 度)としてテンプレートを再利用やりやすいのですが、残念なクライアントまで、フルのC#とは止まらないから派生する追加。

すべての回答をしていないと考え多型がん由来の参考用の由来は、Equalsと比較してもよりベースを参考にした。をご覧ください質問/ディスカッション/回答はこちら 平等と多様性の研究

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top