In the example code below I am taking a list of strings and concatenating them to a delimited string. The problem occurs when I use the setter with an empty list. The ToString method throws an ArgumentOutOfRangeException since the second parameter is a -1.
How should conditions (exceptions thrown in getters/setters) like this be handled?
I don't like the fact that the setter throws an exception since the caller doesn't know about the internals of the class and therefor should not have to handle (or even know how) the exception. Catching all exceptions in the getter/setter and quietly handling them also sounds like a bad idea since the caller will not know the getter/setter failed.
//I realize that this isn't the best code but I wanted to produce an example
//to demonstrate my question.
private string theStringVariable;
const string DELIMITER = ",";
public IList<string> StringList
{
set
{
StringBuilder stringBuilder = new StringBuilder();
foreach(string entry in value)
{
stringBuilder.Append(entry);
stringBuilder.Append(DELIMITER);
}
theStringVariable = stringBuilder.ToString(0, stringBuilder.Length - 1);
}
}
You should check for the potential, common error conditions, and throw your own exception (prior to the StringBuilder errors) right up front, with a meaningful error message.
In your case, you'll most likely want to use some form of ArgumentException if the setter is called with an Empty string list. The key here is that your exception can say "the argument contained an empty collection" instead of "index out of bounds", which is going to make the caller understand, immediately, why they have a "real" problem in their call.
On a side note: In cases like the code you posted - I'd also consider making this a method instead of a property. You're doing quite a bit of "work" in this property setter, which is going to be somewhat unexpected. By making this a method, you'll be giving the user a clue that there's a bit of "processing" occurring within this property...
I don't think your issues deal with best practices.
The best practice you need to watch in your case is the line that says
stringBuilder.ToString(0, stringBuilder.Length - 1);
You are causing the exception to be thrown by not checking the string length. If your length is 0, just return empty string.
If we are talking in generalities, if you have the ability to code around common issues, empty sets, badly formatted data, then you should do your best to shield the user from unnecessary errors.
However* sometimes it is better to abruptly/loudly fail then it is to silently fail.
First of all, if you can spot someone that might cause an exception --- fix it so the exception doesn't happen. In this case, check for an empty list before the loop and set the varaible appropriately.
Otherwise, catch the exceptions (the one you expect might happen(*)), an throw a new more appropriate exception (with the original as the inner exception)
(*) Catch only the one's you expect might happen -- let the unexpected one bubble up to the user.
Code Complete suggests if you can handle the exception locally that you do so: "Don't use an exception to pass the buck". In the example given this would mean check for an empty value and handle this appropriately in the setter.
Related
Okay, I have some very simple code which I will post below. Essentially, I have a connection to a database and I want to map a subset of columns in a query to a particular class. The problem is that it is possible for these to be null.
I would like to know if it is possible if an exception is thrown at a particular line, can we resume the entire block from the next line.
So if this code below was to execute and Line 6 catches an error. Is there an elegant way to catch the exception and make the code resume running at line 7. Essentially making it as though line 6 was never executed.
private static Column MapTableToColumn(OracleDataReader reader){
Column c = new Column();
c.ColumnName = Convert.ToString(reader["COLUMN_NAME"]);
c.DataType = Convert.ToString(reader["DATA_TYPE"]);
c.DataLength = Convert.ToInt32(reader["DATA_LENGTH"]);
c.DataPrecision = Convert.ToInt32(reader["Data_Precision"]);//<---Line 6
c.DataScale = Convert.ToInt32(reader["Data_scale"]);//<--- Line 7
c.AllowDBNull = Convert.ToBoolean(reader["ALLOW_DB_NULL"]);
c.IsReadOnly = Convert.ToBoolean(reader["IS_READ_ONLY"]);
c.IsLong = Convert.ToBoolean(reader["IS_LONG"]);
c.IsKey = Convert.ToBoolean(reader["IS_KEY"]);
c.KeyType = Convert.ToString(reader["KEY_TYPE"]);
c.IsUnique = Convert.ToBoolean(reader["IS_UNIQUE"]);
c.Description = Convert.ToString(reader["DESCRIPTION"]);
return c;
}
It is important to note I am not asking for best practice, it is not something I intend to use in actual code (unless its absolutely genius). I simply want to know if this is possible and how one would go about doing this if it were.
My Research
Most of my research is proactive as opposed to reactive. I would attempt to know if it is possible for the given field to be null before it is read from. If it is, then I'd do a check to determine if the field is null and then set it to a default value. It essentially avoids the possibility of an error happening which I believe is a very good solution. I just wanted to attempt this as I know that when an exception is thrown, the most inner exception contains the line number at which it was thrown. Based on this if you put the exception inside of the class throwing the exception you should hypothetically be able to use reflection in order to continue running from its last point. I'm just not sure how you'd go about doing this. I've also considered the possibly of putting try catches around every single line which I think would be very effective; however, I think that it would be very ugly.
No, what you are asking for is not possible in C#.
Instead the proper solution to this problem is to use better parsing methods that won't throw exceptions in the first place. If your input values can be null, then use parsing methods that can accept null values.
The first thing you probably need to do is use nullable types for your int/bool fields, so that you can support null values. Next, you'll need to create your own methods for parsing your ints/bools. If your input is null, return null, if not, use int.TryParse, bool.TryParse (or as for each if your input is the proper type, just cast to object).
Then by using those methods, instead of Convert, you won't be throwing exceptions in the first place (which you shouldn't be doing here even if it could work, because exceptions are for exceptional cases, not expected control flow).
If the exception is expected then it is not exceptional. Never never never catch a null reference exception. A null reference exception is a bug. Instead, write code to avoid the bug.
You can easily write helper methods that test for null, or use methods like Int32.TryParse that can handle malformed strings.
Check for IsDBNull
SqlDataReader.IsDBNull Method
And Reader has methods for each SQL datatype
For example
SqlDataReader.GetSqlBoolean
If the data is in SQL as string (char,nchar) then first check for null and then TryParse
For example
DateTime.TryParse
And ordinal position is faster
This is a sample for a nullable Int16
Int16? ID;
ID = rdr.IsDBNull(4) ? (Int16?)null : rdr.GetInt16(4);
If you want a default
Int16 ID;
ID = rdr.IsDBNull(4) ? 0 : rdr.GetInt16(4);
You'd need a try/catch around every single variable assignment, and you'd need to initialize all your Column instance values before you tried. This would be relatively slow.
As for reflection based on the line number: I wouldn't rely on the line number because one simple, innocent change to the code will throw it off completely.
I'd check for nulls specifically. If you expect them you can't hardly call them "exceptions". The method that does that is reader.IsDBNull. It takes the column index (not the column name) so you'll need to resolve the index using reader.GetOrdinal:
if (reader.IsDBNull(reader.GetOrdinal("Data_Precision"))) {
// It's null
} else {
// It's not null
}
if you think there is a possibility of getting a null pointer exception, should you use an if statement to make sure the variable is not null, or should you just catch the exception?
I don't see any difference as you can put your logic to deal with the null pointer in the if statement, or in the catch block, so which one is best practise?
I would say ALWAYS use logic to catch the exception, not try/catch.
Try/Catch should be used when you validate but some strange thing happens and something causes an error so you can handle it more gracefully.
There is no single answer that will suffice here, it depends.
Let's take a few scenarios so you can see what I mean.
Scenario: Method that takes a reference type parameter that does not accept null
You're defining a method, it takes a reference type parameter, say a stream object, and you don't want to accept null as a legal input parameter.
In this case, I would say that the contract is that null is not a valid input. If some code does in fact call that method with a null reference, the contract is broken.
This is an exception, more specifically, it's an ArgumentNullException.
Example:
public void Write(Stream stream)
{
if (stream == null)
throw new ArgumentNullException("stream");
...
I would definitely not just let the code execute until it tries to dereference the stream in this case, instead crashing with a NullReferenceException, because at that point I lost all ability to react when I know the cause.
Q. Why can't I return false instead of throwing an exception?
A. Because a return value is easy to silently ignore, do you really want your "Write" methods to just silently skip writing because you made a snafu in the calling code, passing the wrong stream object or something that cannot be written to? I wouldn't!
Scenario: Method returns a reference to an object, sometimes there is no object
In this case the contract is that null is a legal result. In my opinion, null is something to avoid because it is quite hard to make sure you handle correctly everywhere, but sometimes it is the best way.
In this case I would make sure to if my way around the result, to ensure I don't crash when the null reference comes back.
Generalisation
If you take a close look at the above two scenarios, you'll note one thing:
In both cases it comes down to what is being expected, what the contract is.
If the contract says "not null", throw an exception. Don't fall back to the old-style API way of returning false because an exceptional problem should not be silently ignored, and littering the code with if statements to ensure every method call succeeds does not make for readable code.
If the contract says "null is entirely possible", handle it with if statements.
Advertising
For getting a better grip on null problems, I would also urge you to get ReSharper for you and your team, but please note that this answer can be applied to any type of exception and error handling, the same principles applies.
With it comes attributes you can embed into your project(s) to flag these cases, and then ReSharper will highlight the code in question.
public void Write([NotNull] Stream stream)
[CanBeNull]
public SomeObject GetSomeObject()
To read more about the contract attributes that ReSharper uses, see
ReSharper NullReferenceException Analysis and Its Contracts
Contract Annotations in ReSharper 7
Well. Exceptions are just that. Exceptions. They are thrown when something unforseen has happened and should not be part of the normal program flow.
And that's what is happening here. You expected the argument to be specified when it's not. That is unexpected and you should therefore throw your own exception informing the user of that. If you want to get bonus points you can also include the reason to WHY the argument must be specified (if it's not obvious).
I've written a series of posts about exceptions: http://blog.gauffin.org/2013/04/what-is-exceptions/
From a performance standpoint it really depends what you're doing. The performance impact from a try/catch block when no exception is thrown is minimal (and if you really need that last few percent of performance, you probably should rewrite that part of your code in C++ anyway). Throwing exceptions does have a major impact on simpler operations such as string manipulation; but once you get file/database operations in the loop they're so much slower that again it becomes a trivial penalty. Throwing across an App Domain will have a non-trivial impact on just about anything though.
Performance in Operations/second:
Mode/operation Empty String File Database Complex
No exception 17,748,206 267,300 2,461 877 239
Catch without exception 15,415,757 261,456 2,476 871 236
Throw 103,456 68,952 2,236 864 236
Rethrow original 53,481 41,889 2,324 852 230
Throw across AppDomain 3,073 2,942 930 574 160
Additional test results along with the source for the tests is available from the article Performance implications of Exceptions in .NET
I would rather suggest you use if-statement for NullReference exception. For other exception, try-catch should be good enough.
The reason I suggest if-statement for NullReference exception is because C# will not tell which variable is null. if that line has more than one object could be null, you will loss track. If you are using if-statement, you can have better logging to help you get the enough information.
The main Question is if it is a good idea to have methods returning Null at all, personally i do not have any problem with this, but as soon as you try to access modifiers of an object returned from this method and you forget to check if it is assigned this becomes an issue.
Ken has a good answer about this:
If you are always expecting to find a value then throw the exception
if it is missing. The exception would mean that there was a problem.
If the value can be missing or present and both are valid for the
application logic then return a null.
See this disscussion abou tthis issue:
Returning null is usually the best idea if you intend to indicate that
no data is available.
An empty object implies data has been returned, whereas returning null
clearly indicates that nothing has been returned.
Additionally, returning a null will result in a null exception if you
attempt to access members in the object, which can be useful for
highlighting buggy code - attempting to access a member of nothing
makes no sense. Accessing members of an empty object will not fail
meaning bugs can go undiscovered.
Some further reading:
No Null Beyond Method Scope
Should We Return Null From Our Methods?
using try catch for the statements is not an good idea. because when you use try catch them it seems that if some error comes the code will not turninate the application. but if you are sure about what kind of error can come you can tap the error at that point. that will not produce any unknown errors. for example.
string name = null;
here i am going to use the name variable and i am sure that this will throw Null Refrance Error .
try
{
Console.writeLine("Name ={0}",name);
}
catch (NullRefranceException nex)
{
//handle the error
}
catch(Exception ex)
{
// handle error to prevent application being crashed.
}
This is not a good practice while you can handle this kind of error and make your code more readable. like.
if(name !=null)
Console.writeLine("Name ={0}",name);
In my experience using if is better but only if you actually expect a null reference pointer. Without any bit of code or context its difficult to say when one option is better than the other.
There's also a matter of optimization - code in try-catch blocks won't be optimized.
In general, try-catch blocks are great because they will break (move to the catch statement) whenever the exception occurs. If-else blocks rely on you predicting when the error will happen.
Also, catch blocks won't stop your code from halting when an error is hit.
Its always better to use Try Catch other than if else
Here Exceptions are two types namely handled and UN-handled exceptions
Even if u want to handle some function when the Exception u can handle it...
Handled exception always allows you to write some implementations inside the Catch block
Eg. An Alert Message, A new Function to handle when such exception occurs.
I have a few functions on Data access layer
public Order RetrieveById(int id)
public List<Order> RetrieveByStatus(OrderStatus status)
Now i am bit confuse on exception raising.
In case of RetrieveById function, id which is less than 1 is an invalid id therefore i feel like raising an exception. And i feel like returning null for the Id which doesn't exist in the database. Then it feels like i am over complicating.
In case of RetrieveByStatus, i feel like returning a empty list when there is no data in the database for that status.
However i have seen that some people raising an exception when RetrieveById cannot return anything but then RetrieveByStatus should not raise exception when there is no record or should it?
Could anyone please clarify these concepts for me?
In the first case i would possibly go for a exception and handle myself,instead of returning null.What if your first method is used in a way that the returned object is saved to a Order reference.There is a very high chance of NullReferenceException being thrown,when someone tries to call a method or property on that object.
For the second method i would go for a empty list as some have suggested.
I would prefer to return null in the first case and an empty list
in the second case.
But if you want to raise exception then You can raise exception for public Order RetrieveById(int id) because it means that id is not valid as calling the first method means that you know the id and the it needs to be there.
In the second case the OrderStatus might be valid and there is not record found against it so returning an empty list is a good idea.
Read MSDN first: Creating and Throwing Exceptions (C# Programming Guide). It lists both situations when you are expected to throw an exception, and when to avoid it.
Also take into account What is the real overhead of try/catch in C#?
In any case you'll have to process either null return or an exception thrown
As for myself, I'd prefer in both your methods not to throw exception explicitly. I'd say, there is nothing bad, if your method returns null, if it failed to find an object by id. Whereas the RetrieveByStatus method could return an empty collection, not null.
Besides you could follow the pattern used in LINQ, where you have, say, Enumerable.First and Enumerable.FirstOrDefault methods (either throwing an exception or returning null), so you could use the appropriate one in a certain situation, when the id is 100% valid or when on the contrary it could be missing. While methods returning a sequence of elements don't throw exceptions if the sequence to return appears to be empty; consider Enumerable.Where.
I like to avoid returning null whenever possible, because NullRefExceptions are much more cryptic than a specific exception, say OrderNotFoundException. Also, code gets pretty obtuse when you have to constantly expect entities to be null. This ought to be an exception case anyway -- where did you get that id if it doesn't exist in the db?
On the cases you suspect this is more likely to throw an error, you could add a DoesObjectExist or TryGet type method (or even extension method).
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
How slow are .NET exceptions?
I've been reading all over the place (including here) about when exception should / shouldn't be used.
I now want to change my code that would throw to make the method return false and handle it like that, but my question is: Is it the throwing or try..catch-ing that can hinder performance...?
What I mean is, would this be acceptable:
bool method someMmethod()
{
try
{
// ...Do something
catch (Exception ex) // Don't care too much what at the moment...
{
// Output error
// Return false
}
return true // No errors
Or would there be a better way to do it?
(I'm bloody sick of seeing "Unhandled exception..." LOL!)
Ask yourself the following question: Is the exception exceptional?
If this can happen in normal program flow, for example, a failure to parse a number typed by the user, don't use an exception.
If this should not normally happen, but rather signifies a problem outside the program's control, such as a missing file, use an exception.
If your question is whether or not the presence of a try...catch block will affect performance, then no.
If your question is whether there is a performance hit in using an exception-based model rather than a return value model, then yes, there is. Having a function like this:
public void DoWork()
{
if(something) throw new Exception(...);
}
Is not going to perform as well under error conditions as a function like this:
public bool DoWork()
{
if(something) return false;
return true;
}
Exceptions have to unwind the stack and kick you out to the nearest catch block in order to work, so there's overhead involved in that. It's simpler to return a status value, but it's also a more choppy interface to deal with when exceptions are not the rule.
However, that isn't the point. If you're writing code where exceptions are the rule, then you have a problem. Exceptions should be used in...exceptional...conditions, such as when you encounter a condition that you could not account for in code.
Consider the types like int and DateTime. These types provide (among others) two different functions for converting string values into corresponding int and DateTime values: Parse and TryParse. Parse uses the exception model, since it's assuming at that point that you'll be passing it a well-formed integer value, so if it gets something else, that's an exceptional condition. TryParse, on the other hand, is designed for when you are not sure about the format of the string, so it uses the return value model (along with an out parameter in order to get the actual converted value).
Exceptions are for exceptional cases. If your // ...Do something is throwing exceptions during normal flow, fix it.
If you have a try/catch block and this block does not throw an exception, it runs at the same speed as if you didn't have the try/catch block wrapping it. It's only when an exception is actually thrown does performance go down, but if you are using exceptions as designed, it doesn't matter as you are now in an exceptional situation. Exceptions should not be used for control flow.
Putting try...catch around code will not really hinder performance, code that may fail should always have a try...catch around it.
However, you should always avoid exceptions being thrown in the first place because these significantly hit performance.
Never throw an exception unless it is truly exceptional!
Your returning false implies a pattern similar to that used with the TryParse() method.
Its just that you shouldn't allow the exception to raise for logic i.e. you shouldn't leave the catch block with responsibility or returning false always. Simply putting, it should not be used for logic.
For example, when you can check for null and return false, you should not call method on null to have a NullReferenceException and let the catch block return false.
Its also a common misconception of developers to think catching Exception is a good idea.
If Exception happened to be a StackOverflowException or an OutOfMemoryException you probably
wouldnt want your application to continue in these cases.
Regarding performance, using exceptions to control program flow would hurt performance significant, partly because each time an exception is thrown the clr must walk the stack to find a catch statement (called stack unwinding)
The TryXXX pattern is one way of attempting to perform some action without an exception being thrown.
Performance-wise, you wouldn't see any difference. It's a micro-optimization to leave out try-catch because it's hindering performance.
However... That said, I'm not convinced your motives to do so are entirely valid. If the function that throws is your own, then I guess it's throwing for a reason and catching the exception might conceal an important error.
I often heard that Exceptions are slow when thrown the first time, as some module or whatever has to be loaded. But, as Blorgbeard said, Exceptions are for exceptional cases. It shouldn't matter.
Consider the following method signature:
public static bool TryGetPolls(out List<Poll> polls, out string errorMessage)
This method performs the following:
accesses the database to generate a list of Poll objects.
returns true if it was success and errorMessage will be an empty string
returns false if it was not successful and errorMessage will contain an exception message.
Is this good style?
Update:
Lets say i do use the following method signature:
public static List<Poll> GetPolls()
and in that method, it doesn't catch any exceptions (so i depend the caller to catch exceptions). How do i dispose and close all the objects that is in the scope of that method? As soon as an exception is thrown, the code that closes and disposes objects in the method is no longer reachable.
That method is trying to do three different things:
Retrieve and return a list of polls
Return a boolean value indicating success
Return an error message
That's pretty messy from a design standpoint.
A better approach would be to declare simply:
public static List<Poll> GetPolls()
Then let this method throw an Exception if anything goes wrong.
This is definitely not an idiomatic way of writing C#, which would also mean that it probably isn't a good style either.
When you have a TryGetPolls method then it means you want the results if the operation succeeds, and if it doesn't then you don't care why it doesn't succeed.
When you have simply a GetPolls method then it means you always want the results, and if it doesn't succeed then you want to know why in the form of an Exception.
Mixing the two is somewhere in between, which will be unusual for most people. So I would say either don't return the error message, or throw an Exception on failure, but don't use this odd hybrid approach.
So your method signatures should probably be either:
IList<Poll> GetPolls();
or
bool TryGetPolls(out IList<Poll> polls);
(Note that I'm returning an IList<Poll> rather than a List<Poll> in either case too, as it's also good practice to program to an abstraction rather than an implementation.)
I believe
public static bool TryGetPolls(out List<Poll> polls)
would be more appropriate. If the method is a TryGet then my initial assumption would be there is reason to expect it to fail, and onus is on the caller to determine what to do next. If they caller is not handling the error, or wants error information, I would expect them to call a corresponding Get method.
As a general rule, I would say no.
The reason I say no is actually not because you're performing a TryGetX and returning a bool with an out parameter. I think it's bad style because you're also returning an error string.
The Try should only ignore one specific, commonly-encountered error. Other problems may still throw an exception with the appropriate exception message. Remember that the goal of a Try method like this is to avoid the overhead of a thrown exception when you expect a particular, single sort of failure to happen more frequently than not.
Instead, what you're looking for is a pair of methods:
public static bool TryGetPolls( out List<Poll> polls );
public static List<Poll> GetPolls();
This way the user can do what's appropriate and GetPolls can be implemented in terms of TryGetPolls. I'm assuming that your staticness makes sense in context.
Consider returning:
an empty collection
null
Multiple out parameters, to me, is a code smell. The method should do ONE THING only.
Consider raising and handling error messages with:
throw new Exception("Something bad happened");
//OR
throw new SomethingBadHappenedException();
No, from my point of view this is very bad style. I would write it like this:
public static List<Poll> GetPolls();
If the call fails, throw an exception and put the error message in the exception. That's what exceptions are for and your code will become much cleaner, more readable and easier to maintain.
Not really - I can see a number of problems with this.
First of all, the method sounds like you'd normally expect it to succeed; errors (cannot connect to database, cannot access the polls table etc) would be rare. In this case, it is much more reasonable to use exceptions to report errors. The Try... pattern is for cases where you often expect the call to "fail" - e.g. when parsing a string to an integer, chances are good that the string is user input that may be invalid, so you need to have a fast way to handle this - hence TryParse. This isn't the case here.
Second, you report errors as a bool value indicating presence or absence of error, and a string message. How would the caller distinguish between various errors then? He certainly can't match on error message text - that is an implementation detail that is subject to change, and can be localized. And there might be a world of difference between something like "Cannot connect to database" (maybe just open the database connection settings dialog in this case and let the user edit it?) and "Connected to database, but it says 'Access Denied'". Your API gives no good way to distinguish between those.
To sum it up: use exceptions rather than bool + out string to report messages. Once you do it, you can just use List<Poll> as a return value, with no need for out argument. And, of course, rename the method to GetPolls, since Try... is reserved for bool+out pattern.
The guidelines say to try to avoid ref and out parameters if they are not absolutely required, because they make the API harder to use (no more chaining of methods, the developer has to declare all the variables before calling the method)
Also returning error codes or messages is not a best practice, the best practice is to use exceptions and exception handling for error reporting, else errors become to easy to ignore and there's more work passing the error info around, while at the same time losing valuable information like stacktrace or inner exceptions.
A better way to declare the method is like this.
public static List<Poll> GetPolls() ...
and for error reporting use exception handling
try
{
var pols = GetPols();
...
} catch (DbException ex) {
... // handle exception providing info to the user or logging it.
}
It depends on what the error message is. For instance, if processing couldn't continue because the database connection wasn't available, etc., then you should throw an exception as other people have mentioned.
However, it may be that you just want to return "meta" information about the attempt, in which case you just need a way to return more than one piece of information from a single method call. In that case, I suggest making a PollResponse class that contains two properties: List < Poll > Polls, and string ErrorMessage. Then have your method return a PollResponse object:
class PollResponse
{
public List<Poll> Polls { get; }
public string MetaInformation { get; }
}
Depends on if an error is a common occurance or if it us truly an exception.
If errors are gunuinely rare and bad then you might want to consider having the method just return the list of polls and throw an exception if an error occurs.
If an error is something that is realtively common part of normal operations, as like an error coverting a string to an integer in the int.TryParse method, the method you created would be more appropriate.
I'm guessing the former is probably the best case for you.
It depends on how frequently the method will fail. In general, errors in .Net should be communicated with an Exception. The case where that rule doesn't hold is when the error condidition is frequent, and the performance impact of throwing and exception is too high.
For Database type work I think an Exception is best.
I'd restate it like this.
public static List<Poll> GetPolls()
{
...
}
It should probably be throwing an exception (the errorMessage) if it fails to retrieve the polls, plus this allows for method chaining which is less cumbersome than dealing with out parameters.
If you run FxCop, you'll want to change List to IList to keep it happy.
I think its fine. I would prefer though:
enum FailureReasons {}
public static IEnumerable<Poll> TryGetPolls(out FailureReasons reason)
So the error strings don't live in the data-access code...
C# Methods should really only do one thing. You're trying to do three things with that method. I would do as others have suggested and throw an exception if there is an error. Another option would be to create extension methods for your List object.
e.g. in a public static class:
public static List<Poll> Fill( this List<Poll> polls) {
// code to retrieve polls
}
Then, to call this, you would do something like:
List<Poll> polls = new List<Poll>().Fill();
if(polls != null)
{
// no errors occur
}
edit: i just made this up. you may or may not need the new operator in List<Poll>().Fill()
Please state your assumptions, constraints, desires/goals, and reasoning; we're having to guess and/or read your mind to know what your intentions are.
assuming that you want your function to
create the polls list object
suppress all exceptions
indicate success with a boolean
and provide an optional error message on failure
then the above signature is fine (though swallowing all possible exceptions is not a good practice).
As a general coding style, it has some potential problems, as others have mentioned.
There is also this pattern, as seen in many Win32 functions.
public static bool GetPolls(out List<Poll> polls)
if(!PollStuff.GetPolls(out myPolls))
string errorMessage = PollStuff.GetLastError();
But IMO it's horrible.
I would go for something exception based unless this method has to run 65times per second in a 3d game physics engine or someting.
Did I miss something here? The question asker seems to want to know how to clean up resources if the method fails.
public static IList<Poll> GetPolls()
{
try
{
}
finally
{
// check that the connection happened before exception was thrown
// dispose if necessary
// the exception will still be presented to the caller
// and the program has been set back into a stable state
}
}
On a design side note, I'd consider pushing this method into a repository class so you have some sort of context with which to understand the method. The entire application, presumably, is not responsible for storing and getting Polls: that should be the responsibility of a data store.