I don't want to have ultra-deep nested blocks, so in cases that variable initialisation could error I would prefer to do it like this:
try
{
var foo = JsonConvert.DeserializeObject<...>(...);
}
catch (JsonReaderException)
{
Console.Write(...);
throw;
}
var bar = GetBar(foo);
Of course it doesn't compile, I'm not allowed to use foo
outside of the try-block that initialises it.
Putting a full type specification right above the block also sucks imo:
List<Dictionary<string, List<(Dictionary<int, int>, Dictionary<string, string>)>>> foo;
try
{
foo = GetFoo();
}
catch (FooException)
{
Console.Write(...);
throw;
}
var bar = GetBar(foo);
Even in less extreme cases like just int foo = 0;
already feels dirty, especially with that confusing unused initial value. The catch
block exits the program anyway.
How can I try-initialise a variable and use it outside of that scope, with minimal repetition and minimal characters typed?
CodePudding user response:
One way to do this would be putting the initialization logic into another method and wrap it with try
/catch
there, so then you can have:
var foo = InitializeFoo();
var bar = GetBar(foo);
private Foo InitializeFoo()
{
try {
// initalize and return foo
}
catch {
throw;
}
}
You can generalize this by passing a delegate
to the Initialize
method that specifies the initiaze logic and use it for anything else.
public T InitializeVariable<T>(Func<T> initializeAction)
{
try {
var x = initializeAction();
return x;
}
catch {
throw;
}
}
CodePudding user response:
A quick and dirty solution is to use dynamic instead of full type specification like this:
dynamic foo;