مشكلة في المقارنة
-
14-11-2019 - |
سؤال
أحاول تنفيذ قائمة مرتبة.لقد قمت بإنشاء الفصل الذي أريد تخزينه في القائمة، ولكن لسبب ما عندما أحاول تشغيل طريقة الفرز، أحصل على استثناء.يبدو أن شيئا وراء الكواليس يمر في null
مرجع في CompareTo
الطريقة التي قمت بتنفيذها.
إليك ما أعتقد أنه رمز ذو صلة.
يتم تعريف كائن البيانات على النحو التالي:
namespace PrioritisedRequestQueue
{
public class XactTask : IComparable<XactTask>
{
public int priority;
public DateTime submitted;
public string name;
public XactTask( int priority, DateTime submitted, string name)
{
this.priority = priority;
this.submitted = submitted;
this.name = name;
}
public int CompareTo(XactTask rhs )
{
//EXCEPTION OCCURS HERE AFTER A NULL RHS HAS BEEN PASSED IN**
Console.WriteLine("comparing " + rhs.priority+"to "+this.priority);
if (rhs.priority <= this.priority)
{
Console.WriteLine("Entered first if");
Console.WriteLine("comparing " + rhs.submitted + "to " +
this.submitted);
if (rhs.submitted <= this.submitted)
{
Console.WriteLine("Entered second if");
return 1;
}
else
{
return -1;
}
}
else
{
Console.WriteLine("In else");
return -1;
}
}
}
}
ويتم تعريف الفئة التي ستحتفظ بالقائمة على النحو التالي:
namespace PrioritisedRequestQueue
{
public class Class1
{
public List<XactTask> tasks;
public Class1()
{
tasks = new List<XactTask>();
}
public void sort()
{
tasks.Sort();
}
public void add(XactTask task)
{
tasks.Add(task);
}
}
}
وهذا هو البرنامج الذي أستخدمه لإجراء الاختبار:
PrioritisedRequestQueue.Class1 tester = new PrioritisedRequestQueue.Class1();
tester.add(new PrioritisedRequestQueue.XactTask(1, DateTime.Now, "test1"));
tester.add(new PrioritisedRequestQueue.XactTask(1, DateTime.Now, "test2"));
Console.WriteLine(tester.tasks[0].name);
Console.WriteLine(tester.tasks[1].name);
tester.tasks.Sort();
مخرجات برنامج الاختبار هي:
comparing 1to 1 Entered first if
comparing 16/05/2011 14:41:57to 16/05/2011 14:41:57
Entered second if
comparing 1to 1 Entered first if
comparing 16/05/2011 14:41:57to 16/05/2011 14:41:57
Entered second if
comparing 1to 1
Entered first if
comparing 16/05/2011 14:41:57to 16/05/2011 14:41:57
Entered second if
comparing 1to 1
Entered first if
comparing 16/05/2011 14:41:57to 16/05/2011 14:41:57
Entered second if
ثم يبدو أنه يمر أ null
rhs في طريقة المقارنة وأحصل على NullReferenceException
عندما يحاول الوصول إلى أولوية rhs.
هل يمكن أن تخبرني لماذا يحدث هذا وما الذي يجب علي فعله لمعالجة ذلك؟
واسمحوا لي أن أعرف إذا كنت بحاجة إلى أي مزيد من المعلومات.
المحلول
عندما أقوم بتشغيل التعليمات البرمجية الخاصة بك، أحصل على InvalidOperationException
لأن CompareTo
لم يتم تنفيذه بشكل صحيح.
لك CompareTo
تطبيق يجب يعود 0
لو rhs
بالضبط مثل this
(أي أن هذا الكائن والكائن الذي تتم مقارنته متساويان).كما لا ينبغي أن تفشل إذا rhs == null
, ، ولكن يجب أن تأمر null
بطريقة متسقة؛يتم ذلك عادةً عن طريق العودة دائمًا 1
لفرز null
قبل كل الكائنات الصالحة.
ال وثائق IComparable.CompareTo يسرد القواعد التالية، التي يجب اتباعها لكي يعمل الفرز بشكل صحيح:
A.CompareTo(A)
مطلوب لإرجاع الصفر.لو
A.CompareTo(B)
يعود الصفر، ثمB.CompareTo(A)
مطلوب لإرجاع الصفر.لو
A.CompareTo(B)
إرجاع الصفر وB.CompareTo(C)
يعود الصفر، ثمA.CompareTo(C)
مطلوب لإرجاع الصفر.لو
A.CompareTo(B)
إرجاع قيمة أخرى غير الصفر ، ثمB.CompareTo(A)
مطلوب لإرجاع قيمة العلامة المعاكسة.لو
A.CompareTo(B)
إرجاع قيمة x التي لا تساوي الصفر ، وB.CompareTo(C)
إرجاع قيمة y من نفس العلامة مثل x ، ثمA.CompareTo(C)
مطلوب لإرجاع قيمة نفس العلامة مثل x و y.
لإصلاح المشكلة، تأكد من أن تنفيذك لـ CompareTo
يعود 0 عندما priority == rhs.priority && submitted == rhs.submitted
.