שאלה- גם C# ופולימורפיזם, וגם XML - תכנות - HWzone פורומים
עבור לתוכן
  • צור חשבון

שאלה- גם C# ופולימורפיזם, וגם XML


binyamin1001

Recommended Posts

אני צריך לכתוב פונקציה, שמקבלת רשימה של מחלקה כלשהיא שכתבתי, ושומרת אותה בתוך קובץ XML.

הבעיה מתחילה בעובדה, שהרשימה יכולה להכיל שני סוגים של איברים- בגלל פולימורפיזם.

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

הסבר קצת פחות מבולגן:

תהי מחלקה אבסטרקטית A, ושתי מחלקות שונות, B ו-C היורשות אותה.

תהי רשימה L, של אברי A.

תהי פונקציה func, שתפקידה לשמור בקובץ XML את הרשימה L.

איך אני יכול לדעת ב-func, האם האיבר הנוכחי הוא B או C.

דוגמאת הקוד עד לרגע זה:

public void insertEmployeeList(List<BE.Employee> l)
{
XElement EmployeeRoot;
string FPath = @"employee.xml";
EmployeeRoot = new XElement("Employees",
from p in l
select new (prop is BE.Driver)? XElement("Driver", new XElement()):XElement()
);
}

הבעיה מתחילה בזה שהתחביר של ה if (או במקרה הזה- אופרטור :?) הוא כנראה לא תקני.

מישהו יודע איך מתעסקים עם זה?

תודה מראש :hi:

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

קודם כל, אתה יכול להשתמש ב-is:

if (employee is B) {
B tmp = employee as B;
// do something with tmp
} else if (employee is C)
C tmp = employee as C;
// do something with tmp
}

אבל זה די סותר את כל הפואנטה של הפולימורפיזם. הדבר הנכון הוא לנצל את הפולימורפיזם לטובתך - ב-A לשים פונקציה וירטואלית כלשהי, ואז פשוט תממש אותה ב-B וב-C בשני האופנים השונים, ופשוט תקרא לפונקציה הזו.

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

שניצל, הבעיה שלי היא לא הפולימורפיזם עצמו, אלא שמירה בפורמט XML של רשימה מסוג A, שיכולה להכיל גם מופעים מסוג B וגם מופעים מסוג C, כאשר לכל אחת מהמחלקות שדות שונים, ואני צריך לשמור את הנתונים בהתאם לשדות.

איך אני משתמש בתחביר כלשהו של is, או כל אופרטור דומה, יחד עם כתיבה ל XML ע"י XElement?

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

טוב, לצערי (או שמא לשמחתי) אני לא ממש מכיר את Linq, אבל אני אראה אם אני אצליח לעזור.

אני לא ממש בטוח מה אתה עושה בשורה של ה-select, אבל לא נראה לך הגיוני שה-new יהיה לפני ה-XElement (ולא אחרי ה-select)?

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

גם אני לא מבין כ"כ את ה Linq, וכל הפונקציה שיצרתי מבוססת על הדוגמא שהמרצה שלנו נתן לנו:

insertStudentList(List<BE.Student> studentList)
{
XElement studentRoot;
string FPath = @"Data.xml";
studentRoot = new XElement("students",
from p in studentList
select new XElement("student",
new XElement("id", p.Id),
new XElement("name",
new XElement("firstName", p.FirstName),
new XElement("lastName" , p.LastName)
)
)
);
studentRoot.Save(FPath);
}

-מצטער על ההזחה המזעזעת, זה מה שהעתקה מAcrobat עושה-

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

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

גם אני לא מומחה ל-linq אבל ברור שאי אפשר לתקוע if באמצע new, אם כבר אז תנסה ככה:

select (prop is BE.Driver)? new XElement("Driver", new XElement()): new XElement()

(וגם זה אני בספק שיעבוד)

כמו שאמרו פה תכנון נכון יותר יהיה להשתמש בפולימורפיזם לטובתך, תיצור פונקציה ב-employee שמחזירה XElement שמייצג את אותו אובייקט עם השדות שלו (נקרא לפונקציה toXml לצורך הדוגמה) ואז פשוט תעשה:

public void insertEmployeeList(List<BE.Employee> l)
{
XElement EmployeeRoot;
string FPath = @"employee.xml";
EmployeeRoot = new XElement("Employees",
from p in l
select p.toXml()
);
}

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

כרגע, הפתרון שמסתמך על פולימורפיזם לא בא בחשבון, כי הרעיון של התרגיל הוא הפרדה של שכבות, כך שרק ה namespace של הנתונים אחראי על כתיבה לנתונים, ולא ה namespace של המחלקות.

ניסיתי להשתמש בתחביר שהצעת- עם הבדל אחד של משפט if-else במקום האופרטור :?, וזה לא עזר. :-\

כשניסיתי עם :? זה עבד! ;D

תודה רבה! :hi:

נ.ב

למה בעצם משפט if-else לא עבד, אבל אופרטור :? עבד? ???

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

שים לב שאם תרצה ליצור עוד סוג של Employee (ז"א מחלה שיורשת ממנה) תצטרך לשנות את הפונקציה insertEmployeeList בהתאם, וכמו שנאמר, זה שובר את עקרון הפולימורפיזם (הפונקציה insertEmployeeList לא צריכה לדעת עם איזה סוג Employee היא עובדת).

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

זה בדיוק העקרון של התרגיל:

לדאוג שאם אני רוצה לשנות את היממוש של פעולה מסוימת, או להוסיף יכולת, אני צריך רק לשנות את המחלקה שאחראית לגישה אל הנתונים, ולא את כל הפרויקט.

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

ארכיון

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

×
  • צור חדש...