AmiralPatate
AmiralPatate

Reputation: 125

TypeInitializationException on a struct with no constructor

I get into a TypeInitializationException. The inner exception is a DivideByZeroException. Looking at the stack trace for the inner exception, I get this:

à System.Decimal.FCallDivide(Decimal& d1, Decimal& d2)
à System.Decimal.op_Division(Decimal d1, Decimal d2)
à DimensionnelJDP.IncertitudeObject..cctor() dans \IncertitudeObject.cs:ligne 108

The code that triggers the exception is this:

IncertitudeObject io = new IncertitudeObject();
io.Compute_E( Config, ( (EmpilementObject)row[ "Empilement" ] ).pile ); //Exception here

My investigations on the issue lead me to see that, when I look inside io, there are bunch of question marks instead of a bunch of variables. Question marks?

The same exception happens regardless of what function I call (including when calling io.ToString()), and io is always full of question marks.

I figured IncertitudeObject doesn't get initialized correctly, though how is beyond me. It doesn't have a constructor, so I'm assuming it uses the default implicit parameterless constructor of the language. So really, I don't know what is happening here.

It was working fine last week, there wasn't significant changes I can remember. The same setup also works on other projects of my solution.


Here is a quick look at my struct:

public struct IncertitudeObject
{
    private decimal ua;
    public decimal Ua{ get { return ua; } }
    //And a dozen more like it

    private static decimal[] Ref_UA_R = { 4.1M / 1000.0M, 8.2M / 1000.0M, 0.0M };
    //This is line 108 that the stack trace points to
    //And there are also a dozen more like it

    //Bunch of functions that do things that are never called when the exception happens

    //Distinct lack of constructor
}

EDIT: So I found the problem. I didn't know about that whole static constructor thing. Apparently, the order of static field was really important. Had to switch from:

    private static decimal[] Ref_UB2_E = { R2 * 10.0M / ( 2.0M * R3 ) / 1000.0M, 20.0M / ( 2.0M * R3 ) / 1000.0M, 50.0M / ( 2.0M * R3 ) / 1000.0M };
    private static decimal R2 = (decimal)Math.Sqrt( 2 );
    private static decimal R3 = (decimal)Math.Sqrt( 3 );

to:

    private static decimal R2 = (decimal)Math.Sqrt( 2 );
    private static decimal R3 = (decimal)Math.Sqrt( 3 );
    private static decimal[] Ref_UB2_E = { R2 * 10.0M / ( 2.0M * R3 ) / 1000.0M, 20.0M / ( 2.0M * R3 ) / 1000.0M, 50.0M / ( 2.0M * R3 ) / 1000.0M };

In hindsight, I should have seen this.

Upvotes: 0

Views: 133

Answers (1)

Kris Vandermotten
Kris Vandermotten

Reputation: 10201

Your exception is in the static constructor. You did not write one explicitely, but one was generated to hold the initialization of static fields.

private static decimal[] Ref_UA_R = { 4.1M / 1000.0M, 8.2M / 1000.0M, 0.0M };

The code in those initializers is placed in a static constructor by the compiler.

While this particular line wont throw a DivideByZeroException, some line like it apparently is.

Upvotes: 1

Related Questions