Reputation: 5348
Suppose we have a class like:
Public Class Question
Private Shared _field as Integer = CrazyIntegersRepository.GetOne()
' Some other useful things go here
End Class
And the method GetOne throws an exception... How can we manage that? Is a good practice to rewrite that into a static constructor?
When is the GetOne method going to be executed if we leave it there in the inline _field declaration?
Upvotes: 1
Views: 291
Reputation: 12613
If you go by p.campbell's suggestion, you'll have to declare at least one instance of the class in order to have the _field
variable initialised. I assume, from the Shared keyword in the declaration of the variable, that you want it to be accessible from all instances of the class whether or not they have been specifically initialised.
In order to achieve that functionality, you'll have to modify your class as follows:
Public Class Question
Private Shared _field as Integer
Shared Sub New()
_field = CrazyIntergersRepository.GetOne()
End Sub
' Some other useful things go here
End Class
Using this method, the _field
variable will be initialised the first time the class is used because the default constructor is declared as Shared. You could optionally wrap the method in a Try...Catch
block in order to trap exceptions that might occur.
Upvotes: 0
Reputation: 100587
Regarding your question around managing the possible exceptions, go with your gut on that one. Any code that can create an exception should be put into a method. In this case, the constructor would be the best place. So perhaps something like:
Public Sub New()
Try
_field as Integer = CrazyIntegersRepository.GetOne()
Catch ex As Exception
'log it / deal with it as you will
End Try
End Sub
Upvotes: 0
Reputation: 1501123
Note: I'm assuming VB works the same as C# here. I'd be surprised if they differed on this.
If you leave it there (and don't have a static constructor), it will depend on the version of .NET you're using. It's only guaranteed to be run "at some point before the first reference to a static field". You can even create instances and the type initializer may not run! If you have a static constructor (even an empty one), the type initializer will be run directly before the first reference to any constructor or any static member. (Basically, almost anything you actually do with it will initialize it.)
The actual observed behaviour has become lazier in .NET 4 compared with .NET 3.5, as I blogged about. Note that this is only talking about the desktop framework; I don't know what Silverlight or the Compact Framework do.
If the method can throw an exception, I'd be tempted to do it rather more lazily in the first place, in a method call, maybe caching the result appropriately. That way, the method can let the exception bubble up and the caller can try again later. That's appropriate if it's a potentially transient exception you're considering. If it's something which indicates the whole system is unusable, it's fine to let the type initializer fail.
Upvotes: 4