Reputation: 1418
After reading this Eric Lippert Article, I understand that the C# compiler doesn't like it if we leave local variables uninitialized.
As I encounter this 'problem' from time to time, I looked at some of my old code and was able to weed out most of the situation where actually don't need uninitialized (SomeClass obj = null
) local variables.
But I came up with a situation where I don't know how to refactor the code.
public void DoSomething(string foo) {
SomeClass obj; // = null;
try {
obj = SomeClass.CreateItem(target);
} catch(CustomException ex) {
// notify UI of error
}
if (obj != null) {
// do something with `obj`
}
}
SomeClass.CreateItem
may fail due to external factors. If it does, I want to notify the user, if not I want to perform an Action.
The C# compiler doesn't want me to leave obj
uninitialized, so I usually assign null
to it.
This feels like a 'hack' now and my question is:
Is there a design flaw in the code above?
And if there is, how should I deal with references at compile time, when I can't determine if they are going to point to an existing object at run time?
Upvotes: 5
Views: 1117
Reputation: 660138
I would refactor the code like this:
private SomeClass TryToCreateItem()
{
try
{
return SomeClass.CreateItem(target);
}
catch(CustomException ex)
{
// notify UI of error
}
return null;
}
public void DoSomething(string foo)
{
SomeClass obj = TryToCreateItem();
if (obj != null) {
// do something with `obj`
}
"Extract method" is my favourite refactoring.
Upvotes: 10
Reputation: 6604
You could refactor it to encapsulate all your code within the try/catch related to that object and if you really do need to do something if it fails then you can use a bool to relate that to the rest of your code:
public void DoSomething(string foo)
{
bool failedCreation = false;
try
{
SomeClass obj = SomeClass.CreateItem(target);
}
catch (CustomException ex)
{
// notify UI of error
failedCreation = true;
}
if (failedCreation)
{
// do other stuff.
}
}
But this doesn't look like what you have in mind. I would just encapsulate everything within the try/catch and be done with it.
Upvotes: 0
Reputation: 203834
The // do something with
obj`` code should be inside the try
block`.
What you're trying to do is run some code that may or may not succeed, and then run some other code only if the previous code succeeded. That's generally a very strong sign that the other code is a part of the same logical block that is dependent on there not being an exception. If there's an exception constructing this object you want this code to be skipped, which is exactly the behavior that you get by including it in the try
block.
Upvotes: 2