具有支持属性的setter中的StackOverflowException

pb1*_*149 6 c# asp.net stack-overflow setter

更新:我已经解决了我遇到的问题,但我不知道为什么这个bug会产生堆栈跟踪.堆栈跟踪导致我完全错误的方向.如果有人能够解释这里发生了什么,我会很感激(并且会将你的答案标记为已接受).请注意,我的原始帖子已被删除.

我有以下课程.其中不相关的部分已被删除:

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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我也有这个类,它使用上面的类的实例,并使用实例中的值创建了一个XML字符串:

class SecondClass
{
    private ClassName classnameInstance;

    public SecondClass(ClassName instance)
    {
        classnameInstance = instance;
    }

    public string PrepareRequest(XMLWriter writer)
    {
        writer.WriteElementString("accounttypedescription", classnameInstance.AccountTypeDescription);
    }
}
Run Code Online (Sandbox Code Playgroud)

以下是生成堆栈跟踪的客户端代码:

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);
}
Run Code Online (Sandbox Code Playgroud)

最后,这是堆栈跟踪:

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
Run Code Online (Sandbox Code Playgroud)

这个堆栈跟踪让我相信我错误地为STPP.SettleDueDate实现了getter/setter.我检查了它们,支持变量等是正确的(我理解,getter/setter循环的常见原因).进一步调试显示,当PrepareRequest()调用此行时,实际生成了堆栈跟踪:

writer.WriteElementString("accounttypedescription", STPPData.AccountTypeDescription);
Run Code Online (Sandbox Code Playgroud)

我发现我错误地为STPPData.AccountTypeDescription实现了getter,因为我创建了一个我在setter中使用的后备属性但是我没有在getter中使用backing属性:

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)
}
Run Code Online (Sandbox Code Playgroud)

我的问题是:

为什么StackOverflowException的堆栈跟踪指向我SettleDueDate.set()时的bug竟是内AccountTypeDescription.get()?

注意:我是C#的新手,我来自LAMP背景.我已经简化了一些代码,但我认为我没有删除任何重要的内容.

Bry*_*rts 1

以下是一些简单的调试步骤,可以缩小问题范围

  • 使用 SettleDueDate 属性打开类
  • 右键单击 SettleDueDate 的属性名称
  • 单击菜单项“查找所有引用”
  • 设置 SettleDueDate 的每个位置,即 'SettleDueDate = "Something or other"' 添加一个断点
  • 运行应用程序并在遇到断点时继续运行,直到连续多次遇到断点为止
  • 当您发现有问题的点并且代码位于断点上而不是继续使用“Step Out”命令和“Step over”命令来追踪堆栈以找出它被递归分配的位置时