9

私はこのようなコードを持っています

public class SomeClass
{
    private static int staticField = 10;
}

コードは実行されず、staticField のデフォルト値は 0 です。また、このコードにより、MVVMlight の SimpleIoc は次のようなコードで例外をスローします。

SimpleIoc.Default.Register<SomeClass>();

上記のコードにより、MVVMLight は例外をスローします。

 Cannot build instance: Multiple constructors found but none marked with PreferredConstructor.

これは非常に奇妙です。Windows 8 で Win8 RTM x64 + VS2012 Express を使用しています。

4

1 に答える 1

12

これは間違いなく MVVMLight の SimpleIoc のバグです。LinqPad で試してみましたが、問題は、クラスに静的フィールドを追加すると、フィールド初期化子によって静的 ctor が追加されることです。

その結果、クラス SomeClass には SimpleIoc の 2 つの ctor があり、説明した例外が発生します。

回避策は、デフォルトのコンストラクターをクラスに追加し、それを で装飾することですPreferredConstructorAttributeが、これにより、SimpleIoc への依存が発生します。

他の解決策は、静的フィールドを定数値に変更することです。

public class SomeClass
{
    private const int staticField = 10;
}

または、Register メソッドのオーバーロードを使用して、インスタンス作成用のファクトリ メソッドを提供します。

SimpleIoc.Default.Register<SomeClass>(() => new SomeClass())

CodePlex の MVVM Light プロジェクトに関するバグ レポートを提出しました。

LinqPad (テスト コード):

    void Main()
{
    var x = GetConstructorInfo(typeof(SomeClass));

    x.Dump();
    x.IsStatic.Dump();
}


public class PreferredConstructorAttribute : Attribute{

}
public class SomeClass{
  private static int staticField = 10;

}

private ConstructorInfo GetConstructorInfo(Type serviceType)
        {
            Type resolveTo = serviceType;


//#if NETFX_CORE
            var constructorInfos = resolveTo.GetTypeInfo().DeclaredConstructors.ToArray();
            constructorInfos.Dump();
//#else
//          var constructorInfos = resolveTo.GetConstructors();
//constructorInfos.Dump();
//#endif

            if (constructorInfos.Length > 1)
            {
                var preferredConstructorInfos
                    = from t in constructorInfos
//#if NETFX_CORE
                       let attribute = t.GetCustomAttribute(typeof (PreferredConstructorAttribute))
//#else
//                     let attribute = Attribute.GetCustomAttribute(t, typeof(PreferredConstructorAttribute))
//#endif
                       where attribute != null
                       select t;

preferredConstructorInfos.Dump();

var preferredConstructorInfo = preferredConstructorInfos.FirstOrDefault ( );
                if (preferredConstructorInfo == null)
                {
                    throw new InvalidOperationException(
                        "Cannot build instance: Multiple constructors found but none marked with PreferredConstructor.");
                }

                return preferredConstructorInfo;
            }

            return constructorInfos[0];
        }
// Define other methods and classes here

問題はライン

var constructorInfos = resolveTo.GetTypeInfo().DeclaredConstructors.ToArray();

これは、2 つの ConstructorInfos を持つ配列を返します。どちらも、PreferredConstructorAttribute なしで定義され、例外が発生します。

于 2012-11-08T08:38:01.037 に答える