1

Is there a way I can initialize a class which contains a static constructor (that throws an exception), without executing the static constructor?

I've tried these so far:

Activator.CreateInstance(typeof(Foo));

FormatterServices.GetUninitializedObject(typeof(Foo));

var s = new XmlSerializer(typeof(Foo));
Foo f = (Foo)s.Deserialize(new StringReader("<Foo></Foo>"));

Aside from using a CRL Profiler api with something like MS Fakes or TypeMock, can this be done using any API in the baseclass library, or perhaps something unmanaged.

Example class that I want to use.

public class Foo
{
    static Foo()
    {
        throw new Exception("Populate Bar from the database, which isn't available.");
    }

    public int Bar { get; set; }
}
Wai Ha Lee
  • 8,598
  • 83
  • 57
  • 92
JJS
  • 6,431
  • 1
  • 54
  • 70
  • 2
    No. From [Static Constructors](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/static-constructors) : "A static constructor ... is called automatically before the first instance is created or any static members are referenced." – itsme86 Jan 28 '19 at 18:59
  • What would you do with the reference once you have it? Would `default(Foo)` be enough? – JSteward Jan 28 '19 at 19:00
  • 4
    Why do you have a class with a static constructor that throws an exception? Maybe your efforts could be spent on rectifying that issue. – itsme86 Jan 28 '19 at 19:14
  • 3
    My psychic powers are telling me this is an XY question. – Ian Kemp Jan 28 '19 at 19:52
  • @JSteward I would access the instance property Bar of the class, within a Unit Test – JJS Jan 28 '19 at 19:56
  • @itsme86 It's a class that exposes Settings for the application, and is not within my capability to modify. I agree the efforts are better spent fixing that, however it's outside my control for purposes of the question. – JJS Jan 28 '19 at 19:57
  • @IanKemp yes, this is XY without the entire context. I should have added a sample class to explain what it is the static constructor is doing that is failing. – JJS Jan 28 '19 at 19:58
  • 1
    There's very little value in trying to write an automated test that's doing crazy things to the code that it's testing like violating it's contract by preventing its static constructor from running. At that point your test is no longer valuable, errors are so likely to be a result of you using it improperly, not bugs in the designed usage, and you won't be able to be confident that your tests are catching problems given that you're preventing portions of the code from running. Either construct the test to use the code properly, or don't waste time with tests that aren't telling you anything. – Servy Jan 28 '19 at 22:00
  • @Servy - It's not crazy to provide a stub in unit testing. That's all I'm attempting to do. It's a shame people create global variables/types using static, and prevent people from doing UnitTests. – JJS Jan 29 '19 at 19:04
  • @JJS As much as you might wish that a type was designed differently to accommodate unit testing better, it *is* crazy to do a bunch of hackery to try to "test" a class designed in a way that prevents effective unit testing. Given the design of the class you're forced to test at a higher level, rather than unit testing, so you can use the class as designed, if you want your tests to be of value. – Servy Jan 29 '19 at 19:14
  • @Servy I will take it under advisement. You seem smart enough to find a better choice of words. Your message delivery is loosing some of it's impact because the choice of words shows contempt for the author. Your argument about changing behavior so one can unit test, when they might better served by an integration test, stands on it's own without the ad-hominem. Thanks for sharing your opinion on a productive way to test static/singleton types. – JJS Jan 29 '19 at 19:29
  • @JJS Stating that a particular course of action is not productive is not an ad hominem argument. I explained why doing this is a bad idea, I said nothing about you, nor is anything about you the basis for my argument. – Servy Jan 29 '19 at 19:39
  • @Servy calling a course of action crazy can infer that the individual taking that action is also crazy. Thank you for clarifying. I rescind my accusation of using ad-hominem. – JJS Jan 29 '19 at 19:43

1 Answers1

0

No, not that I'm aware of, at least directly.

Static constructors are there exactly to be automatically called whenever anything happens either to anything (method, property, ...) static from the class, or when you create the very first instance of that class (if it's possible).

This means, basically, that they are kind of always called, whether you like/want it or not. It's always automatic and it always happens.

One option, though, would be to use some nasty reflection to extract working code, replace (or entirely remove) static constructor and rebuild the class from scratch. This might help a bit on this.

Problem is that another great question arises: how to replace that type during its usage. If it comes from an interface, it might be easier, but if it's a concrete type being directly called, you have got yourself a great challenge.

Now, if you take this to a higher abstraction level, this issue might be solved using other approaches, like proxying that request to some other database, or even translating it to another language.

Anderson Matos
  • 3,132
  • 1
  • 23
  • 33
  • Thanks for your opinion. I haven't found a way to do it without MS Fakes or Typemock either. I have access to the source, and don't need to use reflection. I can't replace the class. I can't replace it's usage either. Both parts are code I don't have authority to change. – JJS Jan 29 '19 at 19:02
  • If you don't have authority to replace class, you mostly likely won't have authority to bypass the constructor, which is there for a very specific reason. Even if bypassing that was possible... – Anderson Matos Jan 30 '19 at 13:28