1

私は VS 2010 で C# 4.0 を使用しており、n セットのオブジェクトの交差または結合を生成しようとしています。

以下は正しく機能します。

IEnumerable<String> t1 = new List<string>() { "one", "two", "three" };
IEnumerable<String> t2 = new List<string>() { "three", "four", "five" };

List<String> tInt = t1.Intersect(t2).ToList<String>();
List<String> tUnion = t1.Union(t2).ToList<String>();
//  this also works
t1 = t1.Union(t2);
//  as does this (but not at the same time!)
t1 = t1.Intersect(t2);

ただし、次の場合はそうではありません。これらはコード スニペットです。

私のクラスは:

 public class ICD10
{
    public string ICD10Code { get; set; }
    public string ICD10CodeSearchTitle { get; set; }
}

以下では:

IEnumerable<ICD10Codes> codes = Enumerable.Empty<ICD10Codes>();
IEnumerable<ICD10Codes> codesTemp;
List<List<String>> terms;
//  I create terms here ----
// and then ...
foreach (List<string> item in terms)
{
    //  the following line produces the correct results
    codesTemp = dataContextCommonCodes.ICD10Codes.Where(e => item.Any(k => e.ICD10CodeSearchTitle.Contains(k)));

    if (codes.Count() == 0)
    {
        codes = codesTemp;
    }
    else if (intersectionRequired)
    {
        codes = codes.Intersect(codesTemp, new ICD10Comparer());
    }
    else
    {
        codes = codes.Union(codesTemp, new ICD10Comparer());
    }                
}
return codes;

上記は、最後に検索されたアイテムの結果のみを返します。

念のため、独自の比較子も追加しましたが、違いはありませんでした。

public class ICD10Comparer : IEqualityComparer<ICD10Codes>
{
    public bool Equals(ICD10Codes Code1, ICD10Codes Code2)
    {
        if (Code1.ICD10Code == Code2.ICD10Code) { return true; }
        return false;
    }
    public int GetHashCode(ICD10Codes Code1)
    {
        return Code1.ICD10Code.GetHashCode();
    }
}

私は明らかな何かを見落としていると確信しています - 私はそれが何であるかを見ることができません!

4

3 に答える 3

3

このコード: return codes; 遅延列挙型を返します。セットを満たすために実行されたクエリはありません。ただし、一部のクエリは、ループを介して毎回実行され、Count を作成します。

この延期された実行は、クロージャーの問題のために問題です...戻り時itemに、最後のループ実行にバインドされます。

これを解決するには、各ループ実行でクエリを強制的に実行します。

if (codes.Count() == 0)
{
    codes = codesTemp.ToList();
}
else if (intersectionRequired)
{
    codes = codes.Intersect(codesTemp, new ICD10Comparer()).ToList();
}
else
{
    codes = codes.Union(codesTemp, new ICD10Comparer()).ToList();
}   
于 2013-04-07T21:54:23.193 に答える
1

独自の比較子を使用している場合は、GetHashCode関数の正しい実装を確認する必要があります。linq 演算子もこの比較を使用します。ここで見ることができます: http://msdn.microsoft.com/en-us/library/system.object.gethashcode(v=vs.80).aspx

ハッシュ関数を "return 0" に変更してみて、問題があるかどうかを確認してください。ICD10Code.GetHashCodeクラスオブジェクトの場合、おそらく異なる値を返します

于 2013-04-07T21:43:06.200 に答える
0

あなたの問題は間違いなく、LINQ拡張メソッドへの接続IntersectまたはUnionLINQ拡張メソッドではありません。私はちょうど次のことをテストしました:

var t1 = new List<ICD10>()
    {
        new ICD10() { ICD10Code = "123" },
        new ICD10() { ICD10Code = "234" },
        new ICD10() { ICD10Code = "345" }
    };
var t2 = new List<ICD10>()
    {
        new ICD10() { ICD10Code = "234" },
        new ICD10() { ICD10Code = "456" }
    };

// returns list with just one element - the one with ICF10Code == "234"
var results = t1.Intersect(t2, new ICD10Comparer()).ToList();

// return list with 4 elements
var results2 = t1.Union(t2, new ICD10Comparer()).ToList();

あなたICD10ICD10Comparerクラスの宣言を使用します。すべてがうまく機能します!LINQ は問題なく動作するため、カスタム コードでバグを検索する必要があります。

于 2013-04-07T21:50:57.560 に答える