อัปเดต: ฉันได้แก้ไขปัญหาที่ฉันพบแล้ว แต่ฉันไม่รู้ว่าทำไมจุดบกพร่องจึงสร้างการติดตามสแต็กอย่างที่มันทำ การติดตามสแต็กทำให้ฉันไปในทิศทางที่ผิดอย่างสิ้นเชิง หากใครสามารถอธิบายสิ่งที่เกิดขึ้นที่นี่ ฉันจะขอบคุณ (และจะทำเครื่องหมายคำตอบของคุณว่ายอมรับ) โปรดทราบว่าโพสต์ต้นฉบับของฉันถูกลบแล้ว
ฉันมีชั้นเรียนต่อไปนี้ ส่วนที่ไม่เกี่ยวข้องได้ถูกลบออกแล้ว:
class ClassName {
private string[] _accountTypes = new string[2] {"ECOM", "MOTO"};
private Dictionary<string, string> _settleDueDateDictionary = new Dictionary<string, string>() {
{"0", "Process immediately."},
{"1", "Wait 1 day"},
{"2", "Wait 2 days"},
{"3", "Wait 3 days"},
{"4", "Wait 4 days"},
{"5", "Wait 5 days"},
{"6", "Wait 6 days"},
{"7", "Wait 7 days"},
};
private string _settleDueDate;
private string _accountTypeDescription;
public string SettleDueDate
{
get
{
DateTime today = DateTime.Today;
long settleDueDate = Convert.ToInt64(_settleDueDate);
return today.AddDays(settleDueDate).ToString("MM/dd/yyyy");
}
set
{
if (!_settleDueDateDictionary.ContainsKey(value)) {
// TODO - handle
}
_settleDueDate = value;
}
}
public string AccountTypeDescription
{
get {
//return AccountTypeDescription; // This would cause infinite recursion (not referring to backing property).
return _accountTypeDescription; // This fixed the StackOverflowException I was faxed with
}
set
{
if (!_accountTypes.Contains(value))
{
// TODO - handle
}
_accountTypeDescription = value;
}
}
}
ฉันยังมีคลาสนี้ซึ่งรับอินสแตนซ์ของคลาสด้านบนและสร้างสตริง XML โดยใช้ค่าจากอินสแตนซ์:
class SecondClass
{
private ClassName classnameInstance;
public SecondClass(ClassName instance)
{
classnameInstance = instance;
}
public string PrepareRequest(XMLWriter writer)
{
writer.WriteElementString("accounttypedescription", classnameInstance.AccountTypeDescription);
}
}
นี่คือรหัสไคลเอ็นต์ที่สร้างการติดตามสแต็ก:
STPPData STPP = new STPPData();
STPP.SiteReference = _secureTradingWebServicesPaymentSettings.SiteReference;
STPP.Alias = _secureTradingWebServicesPaymentSettings.Alias;
STPP.SettleDueDate = Convert.ToString(_secureTradingWebServicesPaymentSettings.SettleDueDate);
STPP.SettleStatus = _secureTradingWebServicesPaymentSettings.SettleStatus;
STPPXml STPPXml = new STPPXml(STPP);
XmlWriterSettings settings = new XmlWriterSettings();
settings.Async = false;
var builder = new StringBuilder();
using (XmlWriter writer = XmlWriter.Create(builder, settings))
{
string xmlRequest = STPPXml.PrepareRequest(writer);
}
สุดท้าย นี่คือการติดตามสแต็ก:
mscorlib.dll!string.GetHashCode()
mscorlib.dll!System.Collections.Generic.GenericEqualityComparer<System.__Canon>.GetHashCode(SYstem.__Canon obj)
mscorlib.dll!System.Collections.Generic.Dictionary<string,string>.FindEntry(string key)
mscorlib.dll!System.Collections.Generic.Dictionary<System.__Canon,System.__Canon>.ContainsKey(System.__Canon key)
ClassName.SettleDueDate.set(string value)
ClassName.SettleDueDate.set(string value)
ClassName.SettleDueDate.set(string value)
// Infinite recursion of this call
การติดตามสแต็กนี้ทำให้ฉันเชื่อว่าฉันใช้ getter/setter สำหรับ STPP.SettleDueDate อย่างไม่ถูกต้อง ฉันตรวจสอบแล้วและตัวแปรสำรอง ฯลฯ ถูกต้อง (ฉันเข้าใจสาเหตุปกติของการวนซ้ำใน getters/setters) การดีบักเพิ่มเติมแสดงให้ฉันเห็นว่าการติดตามสแต็กถูกสร้างขึ้นจริงเมื่อมีการเรียกใช้บรรทัด PrepareRequest()
นี้:
writer.WriteElementString("accounttypedescription", STPPData.AccountTypeDescription);
ฉันค้นพบว่าฉันใช้ getter สำหรับ STPPData.AccountTypeDescription ไม่ถูกต้อง เนื่องจากฉันได้สร้างคุณสมบัติการสำรองข้อมูลที่ฉันใช้ใน setter แต่ฉันไม่ได้ใช้คุณสมบัติการสนับสนุนใน getter:
public string AccountTypeDescription
{
get {
//return AccountTypeDescription; // This would cause infinite recursion.
return _accountTypeDescription; // This fixed the StackOverflowException
}
// setter omitted for clarity (it is in the examples above)
}
คำถามของฉันคือ:
เหตุใดการติดตามสแต็กของ StackOverflowException จึงชี้ให้ฉันไปที่ SettleDueDate.set() ทั้งที่จริงๆ แล้วจุดบกพร่องนั้นอยู่ภายใน AccountTypeDescription.get()
หมายเหตุ: ฉันยังใหม่กับ C# และมาจากพื้นหลัง LAMP ฉันทำให้โค้ดง่ายขึ้นเล็กน้อย แต่ฉันไม่คิดว่าจะลบสิ่งที่สำคัญออกไป
_settleDueDateDictionary
คืออะไร (รหัส) ก็แทบจะเป็นไปไม่ได้เลยที่จะช่วย - person Erik Philips   schedule 07.12.2012StackOverflowException
- person jenson-button-event   schedule 07.12.2012DateTime
- person Servy   schedule 07.12.2012SettleDueDate = value;
อยู่ที่ไหนสักแห่งในตัวตั้งค่า (แทนที่จะเป็น_settleDueDate = value;
) หรืออะไรทำนองนั้น - person rsbarro   schedule 07.12.2012_settleDueDateDictionary
theSettleDueDate
getter and setter และตัวแปรสำรอง_settleDueDate
ส่วนตัว สิ่งเดียวที่ฉันเปลี่ยนแปลงคือวิธีการส่งanIntParameterHere
ไปยังผู้ตั้งค่า ฉันไม่คิดว่านั่นอาจเป็นปัญหา? ฉันจะให้อะไรอีกบ้าง?ClassName
มิฉะนั้นจะมีเพียง getters/setters อื่นๆ และสมาชิกข้อมูลอื่นๆ สองสามราย - person pb149   schedule 07.12.2012DateTime
ทั่วทั้งแอปพลิเคชันของคุณ จากนั้นแปลงเป็นสตริงก่อนที่คุณจะจัดเก็บไว้ในไฟล์ XML แทนที่จะดำเนินการกับมันทั่วทั้งแอปพลิเคชันของคุณเป็นสตริง - person Servy   schedule 07.12.2012SettleDueDate
อยู่ที่ไหน? เป็นไปได้ไหมที่คุณส่งค่าAccountTypeDescription
เข้าไปและ/หรือใช้เป็นคีย์พจนานุกรม - person Bobson   schedule 10.12.2012STPP.SettleDueDate = Convert.To
...) คือส่วนที่ตั้งค่าSettleDueDate
ขอบคุณ. - person pb149   schedule 10.12.2012