מקבל שגיאת ריצה בהדפסת איבר ברשימה מקושרת - תכנות - HWzone פורומים
עבור לתוכן
  • צור חשבון

מקבל שגיאת ריצה בהדפסת איבר ברשימה מקושרת


bdoron

Recommended Posts

לאור העובדה שאני לא הכי שולט בכתיבה של רשימות מקושרות החלטתי להתאמן בנושא ולסגור את הפינה הזאת של רשימות מקושרות :)

וככה עלה לי בראש לעשות רשימה מקושרת אבל שהיא תהיה generic , יצרתי אותה זה הקוד:


namespace GenericLinkedList
{
class Node<T>
{
public T Data;
public Node<T> next;
public Node()
{

}


}
}


הוספה של איבר לרשימה זה הקוד:


namespace GenericLinkedList
{
public class CustomLinkedList<T>
{
Node<T> head = new Node<T>();


public CustomLinkedList()
{


}
public void AddNode(T obj)
{
Node<T> temp = new Node<T>();
temp.Data = obj;
temp.next = head;
head = temp;
}
public void Print()
{
Node<T> temp = head;
dynamic per;
while(temp!=null)
{
per = temp.Data;
per.Print();
temp = temp.next;
}
}


}
}

ואז הוא יוצר לי אקספשן על הפונקציה של הPrint , ככה קראתי לה בפרויקט אחר אחרי שהוספתי את הפרויקט כDLL

זה המחלקה של הperson


class Person
{
string name;


string id;


public string Name
{
get { return name; }
set { name = value; }
}
public string Id
{
get { return id; }
set { id = value; }
}
public void Print()
{
Console.WriteLine(" name is:{0} and Id is:{1}", this.Name, this.Id);
}
}


וזה הmain שלי, חשוב לי לציין שההוספה של איבר לרשימה עובדת כמו שצריך, רק ההדפסה לא עובדה ...



static void Main(string[] args)
{
CustomLinkedList<Person> arr=new CustomLinkedList<Person>();
Person p = new Person();
p.Name = "boaz";
p.Id = "2452452";
Person p2 = new Person();
p2.Name = "evi";
p2.Id = "111111";


arr.AddNode(p);
arr.AddNode(p2);


arr.Print();


}

כמו שאתם רואים אני מוסיף לרשימה איבר מסוג person ואחרי זה בתוך הלולאה שאני רץ על האיברים ברשימה אני מפעיל את הפונקציה print של כל איבר

ועל זה הוא נופל לי ואין לי שמץ למה

ואיך אני מסדר את זה ..

קישור לתוכן
שתף באתרים אחרים

  • תגובות 43
  • נוצר
  • תגובה אחרונה

למה אתה משתמש ב-dynamic? תעיף את זה. זה דבר מכוער שצריך להשתמש בו רק במקרים מאוד ספציפיים.

אם אתה רוצה להדפיס תשתמש ב-ToString, או שתגדיר לך ממשק בשם Printable עם פונקציית Print ותעשה casting (אם זה אפשרי כמובן).

ובלי קשר, כשאתה מקבל שגיאה תאמר לנו מהי, אנחנו לא אמורים לנחש.

קישור לתוכן
שתף באתרים אחרים

אני אגיד לך מה הבעיה, בגלל שאני עשיתי את הפרויקט של הDLL generic לחלוטין כאשר הגדרתי T Data ואני אחרי זה מציב ברשימה המקושרת הזאת איברים מסוג Person

אז המשתנה מסוג T לא יודע שלאובייקט הזה יש פונקציה בשם print

זה האקספשן שאני מקבל

Unhandled Exception: .CSharp.RuntimeBinder.RuntimeBinderException: 'obj

ect' does not contain a definition for 'Print'

at CallSite.Target(Closure , CallSite , Object )

at System.Dynamic.UpdateDelegates.UpdateAndExecuteVoid1[T0](CallSite site, T0

arg0)

at GenericLinkedList.CustomLinkedList`1.Print() in c:\Projects\GenericLinkedL

ist\GenericLinkedList\CustomLinkedList.cs:line 31

at PersonLinkedList.Program.Main(String[] args) in c:\Projects\PersonLinkedLi

st\PersonLinkedList\Program.cs:line 25

קישור לתוכן
שתף באתרים אחרים

כמו שאמרתי בהודעה הקודמת: אל תשתמש ב-dynamic. זו תוספת מאוחרת לשפה שיוצרת קוד מאוד בעייתי (היא גורמת לכך ששגיאות בזמן קומפילציה הופכות לשגיאות בזמן ריצה, שזה הרבה הרבה יותר גרוע). יש לה שימושים ספציפיים, אבל אל תשתמש בה.

יש שתי דרכים נכונות לעשות את זה:

א. להשתמש ב-ToString - השפה מבטיחה שלכל אובייקט תהיה הפונקציה הזו.

ב. להגדיר ממשק בשם IPrintable שיש בו פונקציה אחת בשם Print, ואז לעשות ש-Person יממש את הממשק הזה. בפונקצית ה-Print של ה-CustomLinkedList אתה יכול לבדוק אם האיבר הוא IPrintable (באמצעות האופרטור is) ואם כן, לבצע casting ל-IPrintable, ואז תוכל לקרוא לפונקציה Print.

קישור לתוכן
שתף באתרים אחרים

תודה על זה שאתם עוזרים לי , זה אחד! דבר שני, אם זה הסיבה שנפלתי בראיון עבודה בJAVA אני צריך לדעת את זה , כי הרבה מקומות אוהבים לקחת נושאים שC שארפ נותן להם פונקציות מוכנות ובתור ראיון עבודה אומרים לך תבנה אחד כזה בלי להשתמש בautocompliation

א. להשתמש ב-ToString - השפה מבטיחה שלכל אובייקט תהיה הפונקציה הזו.

זה פונקציה שהיא הופכת אובייקט לסטרינג

מה הקשר יואב? אני יודע שאני משתמש בToString בשביל casting ממשתנים שהם לא string לstring

קישור לתוכן
שתף באתרים אחרים

אבל האוביקט עצמו של הperson מכיל כבר 2 פרמטרים מסוג string אז אני לא צריך לעשות להם Tostring

מה שכן ניראה לי שהכי הגיוני זה באמת שאני אעשה interface ואני אעשה בפנים מתודה שאני אעשה לה אוברייד בפרויקט של הperson שעשיתי..

קישור לתוכן
שתף באתרים אחרים

וואלה לא חשבתי לעשות דבר כזה , אבל זה אומר שאני צריך לעשות override לפונקציהי Tostring במחלקה Person.

הבנתי נכון?

- - - תגובה אוחדה: - - -

מימשתי את הTostring , וזה עובד, באמת הוא מדפיס לי , אבל אז הוא קורס לי, רושם לי

Name is :eviand ID is: 111111

Name is :boazand ID is: 2452452

Unhandled Exception: System.NullReferenceException: Object reference not set to

an instance of an object.

at GenericLinkedList.CustomLinkedList`1.Print() in c:\Projects\GenericLinkedL

ist\GenericLinkedList\CustomLinkedList.cs:line 30

at PersonLinkedList.Program.Main(String[] args) in c:\Projects\PersonLinkedLi

st\PersonLinkedList\Program.cs:line 25

כמו שאתם רואים זה מדפיס לי, אבל הלולאה כניראה מנסה להדפיס פעם אחרונה את האובייקט, ואז הוא מנסה להדפיס null כי האובייקט האחרון תמיד null

קישור לתוכן
שתף באתרים אחרים

נכון אז אני לא מבין למה הלולאה ממשיכה לעשות לי עוד איטרציה

זה הלולאה :


public void Print()
{
Node<T> temp = head;

while(temp!=null)
{
Console.WriteLine(temp.Data.ToString());
temp = temp.next;
}
}

קישור לתוכן
שתף באתרים אחרים

וכבר הסברתי קודם מה הבעיה שלך:

הבעיה דווקא נובעת מזה שראש הרשימה הוא node שה-data שלו הוא null. גם אם הקוד היה כתוב בצורה תקינה הוא עדיין היה עף, אבל על null reference exception.

דהיינו - שימו לב למה מאותחל head בבנאי.

קישור לתוכן
שתף באתרים אחרים

למה הhead null?

תסתכל על המתודה שיצרתי שמוסיפה איבר לרשימה


public void AddNode(T obj)
{
Node<T> temp = new Node<T>();
temp.Data = obj;
temp.next = head;
head = temp;
}

בפעם הראשונה שהhead נוצר אתה צודק הוא באמת null

אבל שאני מוסיף איבר? אני יוצר צומת שאני מציב בתוכה person את האובייקט שמכיל null אני מציב אותו בnext ואחרי זה בhead עצמו אני מציב את הצומת שיצרתי הtemp שהוא לא מכיל null הוא מכיל את האובייקט person שיצרתי..

קישור לתוכן
שתף באתרים אחרים

כשאתה רק יוצר את הרשימה, כמה אובייקטים מטיפוס Node יש בה? מה ה-Data של כל אחד מהם? מה יקרה אם תנסה להדפיס את הרשימה?

אחרי שהוספת node אחד, כמה אובייקטים מטיפוס Node יש ברשימה? מה ה-Data של כל אחד מהם? מה יקרה אם תנסה להדפיס את הרשימה?

קישור לתוכן
שתף באתרים אחרים

כאשר אני מתחיל יש לי 2 צמתים, אחד הhead עצמו ואחד הnext., אחרי זה אני מציב את התוכן של הhead בתוך הnext... ככה שהוא נשאר עדיין null , אבל את האובייקט person אני מציב בhead עצמו ואז יש לי אחרי הוספת איבר אחד יש לי את הhead עצמו שהוא לא null ואת הnext שלו שהוא null

קישור לתוכן
שתף באתרים אחרים

ארכיון

דיון זה הועבר לארכיון ולא ניתן להוסיף בו תגובות חדשות.


×
  • צור חדש...