Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In WinRT, static field not initialized at all

I have the code like this

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

The code never gets executed and staticField has default value 0. Also the code causes MVVMlight's SimpleIoc to throw an exception with code like this:

SimpleIoc.Default.Register<SomeClass>();

Above code causes MVVMLight to throw an exception saying

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

This very bizarre. I'm using Win8 RTM x64 + VS2012 Express for Windows 8.

like image 869
imgen Avatar asked Nov 08 '12 07:11

imgen


People also ask

Why static variables are not initialized?

Statics are initialized one by one in the order as declared in the source code. Since the first static is initialized before the rest, during its initialization the rest of the static fields are null or default values.

Can we initialize static variable in non-static constructor?

Static constructor can initialize only static variable but non-static constructor can initialize both static and non-static variable.

How do you initialize a static variable in Junit?

You could call the main method of classA . i.e. ClassA. main(somestrArray) and it should do the initialization. But if you don't want to do that then you could create your junit test in the same package as the original class and you would be able to access the protected variables .

Can we initialize static variable in constructor?

If you declare a static variable in a class, if you haven't initialized it, just like with instance variables compiler initializes these with default values in the default constructor. Yes, you can also initialize these values using the constructor.


1 Answers

This is definitely a bug in SimpleIoc of MVVMLight. I have tried it with LinqPad and the problem is when you add a static field to the class an static ctor is added by the field initializer.

The result is that the class SomeClass has two ctors for SimpleIoc, what results in the exception you described.

A Workaround would be to add a default constructor to the class and decorate it with the PreferredConstructorAttribute but this will result in a dependency to SimpleIoc.

Other solution would be to change your static field to a constant value.

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

or to use an overload of the Register method to provide a factory method for instance creation.

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

I have submitted a bug report on the MVVM Light project on CodePlex

LinqPad (Test code):

    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

The problem is the line

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

that returns an array with 2 ConstructorInfos both defined without the PreferredConstructorAttribute which results in the exception.

like image 142
Jehof Avatar answered Sep 24 '22 07:09

Jehof