3

したがって、次のラムダ式はコレクション内の要素を返しませんが、ステップ実行中に 1 つの項目が条件に一致することを確認できました。IEquatable 実装を使用してクラスのサンプルを追加しました。

...within a method, foo is a method parameter
var singleFoo = _barCollection.SingleOrDefault(b => b.Foo == foo);

上記は何も返しません。上記の式を機能させるために何をすべきかについて何か提案はありますか?

public class Foo: IEquatable<Foo> 
{
    public string KeyProperty {get;set;}
    public bool Equals(Foo other)
    {
        if (ReferenceEquals(null, other)) return false;
        if (ReferenceEquals(this, other)) return true;
        return other.KeyProperty==KeyProperty;
    }
    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        if (ReferenceEquals(this, obj)) return true;
        if (obj.GetType() != typeof (Foo)) return false;
        return Equals((Foo) obj);
    }
    public override int GetHashCode()
    {
        return (KeyProperty != null ? KeyProperty.GetHashCode() : 0);
    }
}

私が狂っていないことを確認するために、パスする次の nUnit テストを作成しました。

    [Test]
    public void verify_foo_comparison_works()
    {
        var keyString = "keyValue";
        var bar = new Bar();
        bar.Foo = new Foo { KeyProperty = keyString };
        var basicFoo = new Foo { KeyProperty = keyString };
        var fromCollectionFoo = Bars.SingleFooWithKeyValue;
        Assert.AreEqual(bar.Foo,basicFoo);
        Assert.AreEqual(bar.Foo, fromCollectionFoo);
        Assert.AreEqual(basicFoo, fromCollectionFoo);
    }

== と != をオーバーライドしようとしています:

    public static bool operator ==(Foo x, Foo y)
    {
        if (ReferenceEquals(x, y))
            return true;
        if ((object)x == null || (object)y == null)
            return false;
        return x.KeyProperty == y.KeyProperty;
    }
    public static bool operator !=(Foo x, Foo y)
    {
        return !(x == y);
    }
4

4 に答える 4

5

それらはEqualityComparer<T>.Default等値比較とComparer<T>.Default順序付き比較に使用します。

MSDN -EqualityComparer<T>.Default備考:

このプロパティは、 type がジェネリック インターフェイスを実装しているDefaultかどうかをチェックし、実装されている場合は、その実装を使用する を返します。それ以外の場合は、およびによって提供されるオーバーライドを使用する を返します。TSystem.IEquatable(Of T)EqualityComparer(Of T)EqualityComparer(Of T)Object.EqualsObject.GetHashCodeT

MSDN -Comparer<T>.Default備考:

このComparer(Of T)プロパティによって返される は、System.IComparable(Of T)ジェネリック インターフェイス ( IComparable<T>C# の場合IComparable(Of T)、Visual Basic の場合) を使用して 2 つのオブジェクトを比較します。typeがジェネリック インターフェイスをT実装していない場合、このプロパティはインターフェイスを使用する を返します。System.IComparable(Of T)Comparer(Of T)System.IComparable

于 2010-02-25T21:39:10.850 に答える
4

== 演算子を再定義していません。

への変更:

var singleFoo = _barCollection.SingleOrDefault(b => b.Foo.Equals(foo));
于 2010-02-25T21:41:35.650 に答える
0

IdentityKeyクラス(暗黙のGuid変換がある)で同様の問題が発生しました。この場合、== operatorオーバーライドを含めることは実際には不可能です。

「混合」比較では、==演算子のオーバーロードのあいまいさを回避するために型をキャストする必要があるため、これは実行不可能だと思います。 すなわち。代わりif(guidValue = identityKeyValue)if((IdentityKey)guidValue == identityKeyValue)

使用.Equalsすることは解決策ですが、それは私には自然に感じませんか?

于 2010-07-13T15:43:21.933 に答える
0

== 演算子もオーバーライドする必要があります。

于 2010-02-25T21:40:56.617 に答える