更新:発生していた問題を修正しましたが、バグがスタック トレースを生成した理由がわかりません。スタック トレースは、完全に間違った方向に私を導きます。誰かがここで何が起こっているのかを説明できれば、私はそれを感謝します (そして、あなたの答えを受け入れたものとしてマークします)。私の元の投稿は削除されていることに注意してください。
次のクラスがありました。関係のない部分は削除されました。
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
このスタック トレースにより、STPP.SettleDueDate の getter/setter を間違って実装したと思いました。私はそれらをチェックし、バッキング変数などは正しかったです(ゲッター/セッターのループの通常の原因は理解しています)。PrepareRequest()
さらにデバッグすると、次の行が呼び出されたときにスタック トレースが実際に生成されたことがわかりました。
writer.WriteElementString("accounttypedescription", STPPData.AccountTypeDescription);
セッターで使用するバッキング プロパティを作成したが、ゲッターでバッキング プロパティを使用していなかったため、STPPData.AccountTypeDescription のゲッターを正しく実装していないことがわかりました。
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)
}
私の質問は:
バグが実際には AccountTypeDescription.get() 内にあるのに、StackOverflowException のスタック トレースが SettleDueDate.set() を示しているのはなぜですか?
注: 私は C# を初めて使用し、LAMP のバックグラウンドを持っています。コードを少し簡略化しましたが、重要なものを削除したとは思いません。