سؤال

هذا ما أحاول القيام به.أنا الاستعلام عن ملف XML باستخدام LINQ to XML الذي يعطي لي رسالة IEnumerable<T> كائن ، حيث T هو "القرية" الدرجة مليئة نتائج هذا الاستعلام.بعض النتائج تتكرر, لذلك أود أن أداء متميزة() على IEnumerable كائن مثل ذلك:

public IEnumerable<Village> GetAllAlliances()
{
    try
    {
        IEnumerable<Village> alliances =
             from alliance in xmlDoc.Elements("Village")
             where alliance.Element("AllianceName").Value != String.Empty
             orderby alliance.Element("AllianceName").Value
             select new Village
             {
                 AllianceName = alliance.Element("AllianceName").Value
             };

        // TODO: make it work...
        return alliances.Distinct(new AllianceComparer());
    }
    catch (Exception ex)
    {
        throw new Exception("GetAllAlliances", ex);
    }
}

كما الافتراضي comparer لن تعمل على القرية الكائن ، وأنا نفذت مخصص واحد ، كما رأينا هنا في AllianceComparer الدرجة:

public class AllianceComparer : IEqualityComparer<Village>
{
    #region IEqualityComparer<Village> Members
    bool IEqualityComparer<Village>.Equals(Village x, Village y)
    {
        // Check whether the compared objects reference the same data.
        if (Object.ReferenceEquals(x, y)) 
            return true;

        // Check whether any of the compared objects is null.
        if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
            return false;

        return x.AllianceName == y.AllianceName;
    }

    int IEqualityComparer<Village>.GetHashCode(Village obj)
    {
        return obj.GetHashCode();
    }
    #endregion
}

متميزة() الأسلوب لا يعمل ، كما لدي بالضبط نفس عدد النتائج مع أو دون ذلك.شيء آخر وأنا لا أعرف إذا كان ممكن عادة ، ولكن لا خطوة إلى AllianceComparer.يساوي() لمعرفة ما يمكن أن يكون مشكلة.
لقد وجدت أمثلة هذا على شبكة الإنترنت, ولكن لا أستطيع أن أجعل تنفيذ العمل.

نأمل شخص ما هنا قد نرى ما يمكن أن يكون الخطأ هنا!شكرا مقدما!

هل كانت مفيدة؟

المحلول

المشكلة GetHashCode.يجب تغيير للعودة إلى تجزئة قانون AllianceName بدلا من ذلك.

int IEqualityComparer<Village>.GetHashCode(Village obj)
{
    return obj.AllianceName.GetHashCode();
}

الشيء هو, إذا Equals يعود true, الكائنات يجب أن يكون نفس رمز التجزئة الذي ليس هو الحال بالنسبة مختلفة Village الكائنات مع نفسه AllianceName.منذ Distinct يعمل عن طريق بناء جدول تجزئة داخليا عليك في نهاية المطاف مع المساواة في الأشياء التي لن تكون مطابقة في كل شيء بسبب تجزئة مختلفة رموز.

وبالمثل ، لمقارنة ملفين ، إذا تجزئة الملفات اثنين ليست هي نفسها ، كنت لا تحتاج إلى التحقق من الملفات أنفسهم في كل شيء.أنها سوف تكون مختلفة.وإلا سوف تستمر في تحقق لمعرفة ما إذا كانوا حقا نفس أم لا.هذا هو بالضبط ما تجزئة الجدول أن Distinct يستخدم يتصرف.

نصائح أخرى

<اقتباس فقرة>   

وreturn alliances.Select(v => v.AllianceName).Distinct();

وهذا سيعود على IEnumerable<string> بدلا من IEnumerable<Village>.

وأو تغيير خط

return alliances.Distinct(new AllianceComparer());

إلى

return alliances.Select(v => v.AllianceName).Distinct();
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top