0

アクセサーから新しいインスタンスを返す際に問題はありますか? もしそうなら、より良いアプローチはありますか?

public class Person
{
    private RecIpDet _ipDet;
    public RecIpDet IpDet
    {
        get 
        {                 
            if(_ipDet == null)
                _ipDet = new RecIpDet();
            return _ipDet; 
        }
    } 
}
4

5 に答える 5

5

フィールドを設定しないため、プロパティが呼び出されるたびに新しいオブジェクトが返されるため、問題があります。

_ipDetnull の場合は設定してから返す必要があります。これは、遅延インスタンス化または遅延初期化と呼ばれます。

public class Person
{
    private RecIpDet _ipDet;

    public RecIpDet IpDet
    {
        get 
        {                 
            if (_ipDet == null)
            {
                _ipDet = new RecIpDet();
            }

            return _ipDet; 
        }
    } 
}

これはスレッドセーフではないことに注意してください。そのため、それが問題になる場合は、より堅牢なメカニズムが必要になります。シングル スレッド アプリケーションの場合、この遅延インスタンス化の方法は問題ありません。

.NET 4.0 以降を使用している場合は、Lazy<T>スレッドセーフであると思われるクラスを使用できます。

public class Person
{
    private Lazy<RecIpDet> _ipDet = new Lazy<RecIpDet>(() => new RecIpDet());

    public RecIpDet IpDet
    {
        get 
        {                 
            return _ipDet.Value; 
        }
    } 
}
于 2012-10-02T14:09:42.937 に答える
5

私たちにとって、使用するのは一般的な方法です:

get
{
    return _ipDet ?? (_ipDet = new RecIpDet());
}
于 2012-10-02T14:12:46.187 に答える
2

あなたのコメントに基づいて、インスタンスを設定するつもりだったように見えるので、これは問題のない遅延インスタンス化の典型的な例です (スレッドセーフではありません)。スレッド セーフについて心配する必要がない場合は、次の方法で問題なく動作します。

get
{
    if (_ipDet == null)
        _ipDet = new RecIpDet();

    return _ipDet
}

ただし、.NET 4.0 を使用している場合はLazy<T>、独自の遅延構築を構築する代わりに、次のことをお勧めします。

public class Person
{
    private Lazy<RecIpDet> _ipDet = new Lazy<RecIpDet>();

    public RecIpDet IpDet
    {
        get { return _ipDet.Value; }
    } 
}

Lazy's Value は、最初の呼び出しで型のコンストラクターを呼び出し、スレッド セーフ (別のものを選択できます) レベルのスレッド セーフでもあります。

于 2012-10-02T14:09:55.287 に答える
1

今のところ、常に新しいオブジェクトを返します。何らかの方法で _ipDet が値に設定されていない限り。これにより、コードの動作が非常に予測不能になります。シングルトン パターンを実装し、return new RecIpDet(); を置き換えます。with _ipDet = new RecIpDet(); または、常に新しいオブジェクトを返すようにします。これは問題ありません。

于 2012-10-02T14:12:29.037 に答える
0

Lazy Instantiationを使用することは非常に珍しいことですが、ほとんどの場合、シングルトンパターンの場合です。ここで、その詳細を確認できます。

シングルトンパターンの実装

このページでは、スレッドセーフにする方法もあります。

これは、アプリケーションのどこからでもアクセスできるグローバルオブジェクトに非常に役立ちます。

于 2012-10-02T14:19:22.490 に答える