0

最近、.NET 3.5 を使用して開発しているアプリケーションの 1 つで、次の興味深いシナリオを観察しました。この特定のアプリケーションでは、静的変数としてアクセスする singletion オブジェクトがあります。.NET ランタイムは、最初にアクセスしたときにこのシングルトン オブジェクトを初期化するはずだと思っていましたが、そうではないようです。.NET ランタイムは、この特定のオブジェクトにアクセスする前にそれを初期化します。以下は、いくつかの疑似コードです。

if(!initSingleton)
   //Do some work without using the singletion class.
else
   //Do some work using the singletion class.

実行時でも、私のコードは if ステートメント内のコードのみを実行します。.NET ランタイムはまだシングルトン オブジェクトを初期化します。一部のアプリケーション実行では、この特定のオブジェクトにアクセスする必要はまったくありません!

また、デバッグ ビルドではこの動作は見られません。これは、最適化されたビルド (リリース ビルド) と関係があるようです。

これは .NET ランタイムの予想される動作ですか?

アップデート:

以下は実際のコードです。

private void InitServiceClient(NetworkCredential credentials, bool https)
        {
            string uri = currentCrawlingWebUrl;
            if (!uri.EndsWith("/"))
                uri = string.Concat(uri, "/");
            uri = string.Concat(uri, siteDataEndPointSuffix);

            siteDataService = new SiteData.SiteDataSoapClient();
            siteDataService.Endpoint.Address = new EndpointAddress(uri);

            if (credentials != null)
            {
                siteDataService.ClientCredentials.Windows.ClientCredential = credentials;
            }
            else if (MOSSStateHandler.Instance.UserName.Length > 0 && MOSSStateHandler.Instance.Password.Length > 0)
            {
                siteDataService.ClientCredentials.Windows.ClientCredential.UserName = MOSSStateHandler.Instance.UserName;
                siteDataService.ClientCredentials.Windows.ClientCredential.Password = MOSSStateHandler.Instance.Password;
                siteDataService.ClientCredentials.Windows.ClientCredential.Domain = MOSSStateHandler.Instance.Domain;
            }

            BasicHttpBinding httpBinding = (BasicHttpBinding)siteDataService.Endpoint.Binding;
            httpBinding.Security.Mode = (https ? BasicHttpSecurityMode.Transport : BasicHttpSecurityMode.TransportCredentialOnly);

            string authmode = MOSSConnectorConfiguration.Instance.Config.GetString(ConfigConstants.SHAREPOINT_AUTH_PROVIDER, "ntlm");
            if (authmode.Equals("ntlm", StringComparison.OrdinalIgnoreCase))
                httpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Ntlm;
            else if (authmode.Equals("kerberos", StringComparison.OrdinalIgnoreCase))
                httpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
            else
                throw new Exception(string.Format("Not supported"));
        }

クラスMOSSStateHandlerが初期化されるのをブロックする場合、私のアプリケーションはサイドelseでコードを実行しません。

4

2 に答える 2

3

C# のシングルトン パターンに関するJon Skeet の記事と、遅延読み込みなどに関する付録を読むことをお勧めします。実装の問題について理解を深めることができます。

于 2009-12-17T14:32:18.563 に答える
2

C# 言語仕様から:

クラスの静的コンストラクターは、特定のアプリケーション ドメインで最大 1 回実行されます。静的コンストラクターの実行は、アプリケーション ドメイン内で次のイベントの最初の発生によってトリガーされます。

  • クラスのインスタンスが作成されます。
  • クラスの静的メンバーのいずれかが参照されています。
于 2009-12-17T14:27:13.700 に答える