デバッガーをアタッチ (F5) して Visual Studio 内からアプリを起動すると、アプリは正常に動作していました。しかし、デバッガーを接続せずにアプリを起動したとき (Ctrl-F5 または .exe ファイルを起動)、StackOverflowException
幸運にも Windows イベント ログに記録された.
問題のあるコードは次のとおりです。
namespace Caliburn.Micro.Contrib
{
public static class FrameworkExtensions
{
public static class ViewLocator
{
static readonly Func<string,object, IEnumerable<string>> _baseTransformName = Micro.ViewLocator.TransformName;
public static void EnableContextFallback()
{
Caliburn.Micro.ViewLocator.TransformName = FallbackNameTransform;
}
static IEnumerable<string> FallbackNameTransform(string typeName, object context)
{
var names = _baseTransformName(typeName, context);
if (context != null)
{
names = names.Union(_baseTransformName(typeName, null));
}
return names;
}
}
}
}
FrameworkExtensions.EnableContextFallack()
アプリの起動中にメソッドを呼び出しましたが、最初の呼び出し中に StackOverflowException が発生しましたCaliburn.Micro.ViewLocator.TransformName
。つまり、デバッガーがアタッチされていない場合は が呼び出された後、デバッガーがアタッチされている場合は が呼び出される前に_baseTransformName
、変数が初期化されます。 EnableContextFallback()
EnableContextFallback()
静的コンストラクターを追加することでバグを修正し、コンストラクターで変数を割り当てることができました
namespace Caliburn.Micro.Contrib
{
public static class FrameworkExtensions
{
public static class ViewLocator
{
static readonly Func<string, object, IEnumerable<string>> _baseTransformName;
static ViewLocator()
{
_baseTransformName = Micro.ViewLocator.TransformName;
}
public static void EnableContextFallback()
{
Caliburn.Micro.ViewLocator.TransformName = FallbackNameTransform;
}
static IEnumerable<string> FallbackNameTransform(string typeName, object context)
{
var names = _baseTransformName(typeName, context);
if (context != null)
{
names = names.Union(_baseTransformName(typeName, null));
}
return names;
}
}
}
}
これにより、 の最初の呼び出しの前に変数_baseTransformName
が常に設定されますEnableContextFallback()
。
問題は、デバッガーがアタッチされているときに静的変数の初期化動作が異なるのはなぜですか?また、異なる動作を「無効にする」方法があるのですか?
乾杯