0

プラットフォーム: Visual Studio 2008 SP1、Resharper 4.1、.NET 3.5

GetProperty<T>プロパティ値を遅延して返す静的メソッドを持つクラスがあります。

private static T GetProperty<T>(T backingField, Func<T> factory) 
    where T : class 
{
    if (backingField == null)
        backingField = factory();
    return backingField;
}

しかし、上記のメソッドを使用してプロパティを返すと、プライベート バッキング フィールドが割り当てられていないという 2 つの警告が表示されます。ただし、後で必要な場合にのみ割り当てられます。

代替テキスト

この警告は無視できますか?
-- または --
プロパティをロードする方法に欠陥がありますか?

4

4 に答える 4

13

あなたの方法には欠陥があります。このアプローチを取るには、パラメーターを作成する必要がありbackingFieldますref

private static T GetProperty<T>(ref T backingField, Func<T> factory)

次にGetProperty、パスref _ImagXpressまたはref _PdfXpress

現在行っている方法では、実際のバッキング フィールドではなく、パラメーターに新しい値を割り当てるだけです。

于 2009-04-24T17:44:26.523 に答える
5

あなたのアプローチには欠陥があります。あなたのフィールドは決して何にも設定されません。backingField引数はメソッドで設定されていますが、これは渡すフィールドを更新しません。次のように、キーワードを付けてGetProperty<T>その引数を渡したいと思うでしょう:ref

private static T GetProperty<T>(ref T backingField, Func<T> factory)
于 2009-04-24T17:46:27.957 に答える
3

別の回答のコメントで述べたように、ref パラメーターの必要性はコードの匂いです。まず第一に、これをメソッドで行っている場合、単一責任の原則を破っていることになりますが、さらに重要なことは、コードは継承階層内でのみ再利用可能です。

ここで派生するパターンがあります。

public class LazyInit<T>
    where T : class
{
    private readonly Func<T> _creationMethod;
    private readonly object syncRoot;
    private T _instance;

    [DebuggerHidden]
    private LazyInit()
    {
        syncRoot = new object();
    }

    [DebuggerHidden]
    public LazyInit(Func<T> creationMethod)
        : this()
    {
        _creationMethod = creationMethod;
    }

    public T Instance
    {
        [DebuggerHidden]
        get
        {
            lock (syncRoot)
            {
                if (_instance == null)
                    _instance = _creationMethod();
                return _instance;
            }
        }
    }

    public static LazyInit<T> Create<U>() where U : class, T, new()
    {
        return new LazyInit<T>(() => new U());
    }

    [DebuggerHidden]
    public static implicit operator LazyInit<T>(Func<T> function)
    {
        return new LazyInit<T>(function);
    }
}

これにより、次のことが可能になります。

public class Foo
{
    private readonly LazyInit<Bar> _bar1 = LazyInit<Bar>.Create<Bar>();
    private readonly LazyInit<Bar> _bar2 = new LazyInit<Bar>(() => new Bar("foo"));

    public Bar Bar1
    {
        get { return _bar1.Instance; }
    }

    public Bar Bar2
    {
        get { return _bar2.Instance; }
    }
}
于 2009-04-24T18:16:49.350 に答える
1

別のソリューションを提案するには:

そのロジックを別のメソッドにカプセル化することで、大幅に節約しているとは言えません。あまり利益を得ることなく複雑さを増しています。このようにすることをお勧めします:

protected PdfXpress PdfXpress
{
    get
    {
        if (_PdfXpress == null)
            _PdfXpress = PdfXpressSupport.Create();

        return _PdfXpress;
    }
}

protected ImagXpress ImagXpress
{
    get
    {
        if (_ImagXpress == null)
            _ImagXpress = IMagXpressSupport.Create();

        return _ImagXpress;
    }
}

数行を追加していますが、複雑さは大幅に軽減されています。

于 2009-04-24T17:55:24.923 に答える