Error Handling in C# - c#

Because I am writing my first MVVM application and I never write so "big" application. I have no idea how error handling for users is normally done.
I found some "guide":
http://codebuild.blogspot.co.at/2012/01/15-best-practices-about-exception.html
At first point is mentioned: "Don't manage business logic with exceptions. Use conditional statements instead. If a control can be done with if-else statement clearly, don't use exceptions because it reduces readability and performance (e.g. null control, divide by zero control)."
So is better to use if-else statment? Or how do you do? Or is better only working with try-catch statment?
And later when I have more if-else code statments one in other .. is better to use basic error bool and error string for all over the code? When happend just turning this bool to true state and write message to error string? And later by showing result check if any error happend?
If you dont understand the question please ask, or write how do you handle with errors in code for user?
Any general guide will be welcome :)

As mentioned exceptions decrease performance (not sure about readability, I personally never had a problem with that). If you compare how long it takes to check something with IF statement or with TRY-CATCH, you will notice a huge difference in favor of the first one.
I would say use IF statement everywhere, where you can check validity yourself - if it fails, in else statement you can specify what needs to be done (display message to user etc.). For example when dividing x/y
private static void IfMethod()
{
int x = 10;
int y = 0;
if (y != 0)
{
Console.WriteLine(x / y);
}
else
{
Console.WriteLine("y is 0");
}
}
Try-catch is more for situations where you can't predict everything. For example if you are trying to read/write a file you will never for 100% know if you have access to that particular file, the file system or if the file actually exist. This is especially true if you are writing applications for someone else. You have no way to know how they configured their PC, access rights etc.
Hope this helps.

Don't manage business logic with exceptions. Use conditional
statements instead. If a control can be done with if-else statement
clearly, don't use exceptions because it reduces readability and
performance
True. But let's clarify, what is meant here.
This is a sample, when logic is built on exceptions:
private int? Foo(int a)
{
try
{
// bar is some int field
return bar / a;
}
catch (DivideByZeroException)
{
return null;
}
}
Here, method Foo expects, that a can be 0. Hence, a == 0 isn't an exception. But, instead of this:
private int? Foo(int a)
{
if (a == 0)
return null;
return bar / a;
}
the logic of this method uses an exception to detect, that result of the method is undetermined, and returns special value (null).
On the other hand, here's sample, when you must use exception:
public int Foo(int a)
{
if (a == 0)
throw new ArgumentOutOfRangeException("a can't be 0!");
return bar / a;
}
This version of Foo is a public method from class library. The logic of Foo can't handle the case, when a == 0. So, it must check input parameter, and throw exception.
To re-phrase citation above:
do not throw exceptions, if current state can (and must) be handled by your business logic; use conditional statements instead.
do throw exceptions, if current state is unexpected, and cannot (must not) be handled by your business logic.

Related

Throwing exceptions for legal states in code

The Exception is a convenient container, that is tempting to use for various purposes. But is it OK to use it for handling legal states in your code?
My example: I have a geometric function that finds the closest object within a search radius:
public IPoint FindNearest(IPoint origin, double searchRadius)
{
}
My idea was that I could throw an exception, when the search doesn't find a hit. But is this a good idea? Alternatively, I could return Null (which I don't like), or return a result object instead of a Point.
Exception, in general, represents an invalid or "exceptional" scenario. In your case, if not finding a hit is an exceptional scenario and it should always be found in usual cases then you can throw exception.
You should always try to avoid throwing exception because of its heavy nature. If caller code is calling this method frequently and your method is in result throwing lot of exceptions, it will make your program slow
Best practice is to use exception only if you can not handle the error in a functial way. In this case not finding a location and returning null is best, because your calling function can handle the null in a functional way. Besides the clean code, throwing and handling exceptions is realy bad for performance, so use them only as last resort.
You could do something like
public bool TryFindNearest(IPoint origin, double searchRadius, out IPoint result)
{
// your logic here, return true if you find a point. Otherwise return false.
}
Then your calling code can do something like:
IPoint nearestPoint;
If (TryFindNearest(origin, searchRadius, out nearestPoint))
{
// do your stuff.
}
Exceptions should be used in invalid scenarios not to control program flow.
Usually in this situation throwing exceptions isn't a good idea, they are expensive and semantically mean something else entirely.
You could return null and do a null check, or I occasionally find that using the Special Case pattern works out nicely and makes for readable code if you give the class/interface a sensible name.
In this instance, you'd return either an implementing class or derived interface called something like:
public class NoHitOnRadius : IPoint {}
And return that from the call when you get no hits. Then the calling code checks the return type:
var p = FindNearest(...);
if (p is NoHitOnRadius)
{
// Do something.
}
Although in this specific situation I'd likely go with the TryFindNearest semantics (to keep commonality with the likes of TryParse etc) that RobH suggests.

Advice on generic try catch

This is not so much of a problem but more feedback and thoughts. I have been considering an implementation for methods that have been tested thoroughly through our internal teams. I would like to write a generic exception catch method and reporting service.
I relize this is not as easy as a "try-catch" block, but allows for a uniform method for catching exceptions. Ideally I would like to execute a method, provide a failure callback and log all the parameters from the calling method.
Generic Try-Execute.
public class ExceptionHelper
{
public static T TryExecute<T, TArgs>(Func<TArgs, T> Method, Func<TArgs, T> FailureCallBack, TArgs Args)
{
try
{
return Method(Args);
}
catch (Exception ex)
{
StackTrace stackTrace = new StackTrace();
string method = "Unknown Method";
if (stackTrace != null && stackTrace.FrameCount > 0)
{
var methodInfo = stackTrace.GetFrame(1).GetMethod();
if (methodInfo != null)
method = string.Join(".", methodInfo.ReflectedType.Namespace, methodInfo.ReflectedType.Name, methodInfo.Name);
}
List<string> aStr = new List<string>();
foreach (var prop in typeof(TArgs).GetProperties().Where(x => x.CanRead && x.CanWrite))
{
object propVal = null;
try
{
propVal = prop.GetValue(Args, null);
}
catch
{
propVal = string.Empty;
}
aStr.Add(string.Format("{0}:{1}", prop.Name, propVal.ToString()));
}
string failureString = string.Format("The method '{0}' failed. {1}", method, string.Join(", ", aStr));
//TODO: Log To Internal error system
try
{
return FailureCallBack(Args);
}
catch
{
return default(T);
}
}
}
}
What I know as draw backs.
Performance Loss using reflection
MethodBase (methodInfo) may not be available through optimization
The try-catch around the error handler. Basically I could use the TryExecute wrapper for the try-catch around the error call back however that could result in a stack overflow situation.
Here would be a sample implementation
var model = new { ModelA = "A", ModelB = "B" };
return ExceptionHelper.TryExecute((Model) =>
{
throw new Exception("Testing exception handler");
},
(Model) =>
{
return false;
},
model);
Thoughts and comments appreciated.
That's a lot of code to put in a catch, including two more try/catch blocks. Seems like a bit of overkill if you ask me, with a good amount of risk that a further exception can obscure the actual exception and that the error information would be lost.
Also, why return default(T)? Returning defaults or nulls as indications of a problem is usually pretty sloppy. If nothing else, it requires the same conditional to be wrapped around every call to the method to check for the return and respond to... some error that has gone somewhere else now.
Honestly, that usage example looks pretty messy, too. It looks like you'll end up obscuring the actual business logic with the error-trapping code. The entire codebase will look like a series of error traps, with actual business logic hidden somewhere in the entanglement of it. This takes valuable focus off of the actual intent of the application and puts something of background infrastructure importance (logging) at the forefront.
Simplify.
If an exception occurs within a method, you generally have two sensible options:
Catch (and meaningfully handle) the exception within the method.
Let the exception bubble up the stack to be caught elsewhere.
There's absolutely nothing wrong with an exception escaping the scope of the method in which it occurs. Indeed, exceptions are designed to do exactly that, carrying with them useful stack information about what happened and where. (And, if you add meaningful runtime context to the exception, it can also carry information about why.)
In fact, the compiler even subtly hints at this. Take these two methods for example:
public int Sum(int first, int second)
{
// TODO: Implement this method
}
public int Product(int first, int second)
{
throw new NotImplementedException();
}
One of these methods will compile, one of them will not. The compiler error will state that not all code paths return a value on the former method. But why not the latter? Because throwing an exception is a perfectly acceptable exit strategy for a method. It's how the method gives up on what it's doing (the one thing it should be trying to do and nothing more) and let's the calling code deal with the problem.
The code should read in a way that clearly expresses the business concept being modeled. Error handling is an important infrastructure concept, but it's just that... infrastructure. The code should practically scream the business concept being modeled, clearly and succinctly. Infrastructure concerns shouldn't get in the way of that.
This is very rarely going to be useful.
It covers only cases where:
The method has a well-defined means of obtaining an appropriate return value in the face of failure.
You'd actually care to log that it happened.
Now, 2 is very common with exceptions of all sorts, but not where 1 is true too.
1 of course is rare, since in most cases if you could produce a reasonable return value for given parameters by means X you wouldn't be trying means Y first.
It also has a default behaviour of returning default(T) - so null or all zeros - if the fallback doesn't work.
This only works where your case 1 above has "something that just returns null as a result because we don't really care very much what this thing does", or where the called method never returns null, in which case you then test for null, which means that your real error-handling code happens there.
In all, what you've got here is a way in which exceptions that would be trappable by real code have to be caught for by testing (and sometimes testing + guesswork) instead, and those that would bring down a program in a clear place with nice debugging information will instead put it into a state where you don't know what's going on anywhere, but at least of the few dozen bugs that got logged before something managed to bring it down fully, one of the is probably the actual problem
When you've a catch on some exception for a particular reason, by all means log the exception. Note that this is not so much to help find bugs (if that exception being raised there is a bug, you shouldn't be catching it there), but to cancel out the fact that having a catch there could hide bugs - i.e. to cancel out the very effect you are deliberately encouraging by putting catches all over the place. (E.g. you expect a regularly hit webservice to fail to connect on occasion, and you can go on for some hours with cached data - so you catch the failure and go on from cache - here you log because if there was a bug meaning you were never trying to hit the webservice correctly, you've just hidden it).
It's also reasonable to have some non-interactive (service or server) app log all exceptions that reach the top of the stack, because there's nobody there to note the exception.
But exceptions are not the enemy, they're the messenger. Don't shoot the messenger.

Is it acceptable to use exceptions instead of verbose null-checks?

I recenly encountered this problem in a project: There's a chain of nested objects, e.g.: class A contains an instance variable of class B, which in turns has an instance variable of class C, ..., until we have a node in the tree of class Z.
----- ----- ----- ----- -----
| A | ---> | B | ---> | C | ---> | D | ---> ... ---> | Z |
----- ----- ----- ----- -----
Each class provides getters and setters for its members. The parent A instance is created by an XML parser, and it is legal for any object in the chain to be null.
Now imagine that at a certain point in the application, we have a reference to an A instance, and only if it contains a Z object, we must invoke a method on it. Using regular checks, we get this code:
A parentObject;
if(parentObject.getB() != null &&
parentObject.getB().getC() != null &&
parentObject.getB().getC().getD() != null &&
parentObject.getB().getC().getD().getE() != null &&
...
parentObject.getB().getC().getD().getE().get...getZ() != null){
parentObject.getB().getC().getD().getE().get...getZ().doSomething();
}
I know that exceptions should not be used for ordinary control flow, but instead of the previous code, I have seen some programmers doing this:
try {
parentObject.getB().getC().getD().getE().get...getZ().doSomething();
} catch (NullPointerException e){}
The problem with this code is that it may be confuse when maintaining it, since it doesn't show clearly which objects are allowed to be null. But on the other hand is much more concise and less "telescopic".
Is it an acceptable to do this to save development time?
How could the API be redesigned to avoid this problem?
The only thing I can think of to avoid the long null checking is to provide void instances of the nested objects and providing isValid methods for each one of them, but wouldn't this create a lot of innecesary objects in memory?
(I've used Java code, but the same question can apply to C# properties)
Thanks.
It is bad design if parentObject needs to know that A contains a B which contains a C wich contains.... That way, everything is coupled to everything. You should have a look at the law of demeter: http://en.wikipedia.org/wiki/Law_Of_Demeter
parentObject should only call methods on its instance variable B. So, B should provide a method that allows for the decision, e.g.
public class A {
private B myB;
//...
public boolean isItValidToDoSomething(){
if(myB!=null){
return myB.isItValidToDoSomething();
}else{
return false;
}
}
}
Eventually, at the level of Z, the method has to return true.
Imho, saving development time is never a reason for tolerating problems in the design. Sooner or later these problems will steal you more time than it would have taken to fix the problems in the first place
It's bad practice to use Exceptions here.
There's a hint in the name: Exceptions are for exceptional circumstances (i.e. unexpected) . If nulls are expected values, then encountering them is not exceptional.
Instead, I'd have a look at the class hierarchy and try to understand why such deep access chaining needs to happen. This seems like a big design issue, you shouldn't normally expect the caller to construct calls using deep knowledge of the structure of objects hidden within class A.
Questions you could ask:
Why does the caller need to doSomething() with the Z object anyway? Why not put the doSomething() on class A? This could propagate doSomething() down the chain if needed and if the relevant field was not null....
What does a null mean if it exists in this chain? The meaning of a null will suggest what business logic should be employed to handle it.... which could be different at each level.
Overall, I suspect the right answer is to put doSomething() on each level of the heirarchy and have the implementation something like:
class A {
...
public void doSomething() {
B b=getB();
if (b!=null) {
b.doSomething();
} else {
// do default action in case of null B value
}
}
}
If you do this, then the API user only has to call a.doSomething(), and you have the added bonus that you can specify different default actions for a null value at each level.
Personally I like to avoid this problem altogether by using an option type. By adjusting the value returned from these methods/properties to be Option<T> rather than T the caller can choose how they wish to handle the case of no value.
An option type can either have a contained value or not (but the option itself can never be null), but the caller cannot simply pass it on without unwrapping the value so it forces the caller to deal with the fact there may be no value.
E.g. in C#:
class A {
Option<B> B { get { return this.optB; } }
}
class B {
Option<C> C { get { return this.optC; } }
}
// and so on
If the caller wants to throw, they merely retrieve the value without explicitly checking to see if there is one:
A a = GetOne();
D d = a.Value.B.Value.C.Value.D.Value; // Value() will throw if there is no value
If the caller wants to just default if any step doesn't have a value, they can perform mapping/binding/projection:
A a = GetOne();
D d = a.Convert(a => a.B) // gives the value or empty Option<B>
.Convert(b => b.C) // gives value or empty Option<C>
.Convert(c => c.D) // gives value or empty Option<D>
.ValueOrDefault(new D("No value")); // get a default if anything was empty
If the caller wants to default at each stage, they can:
A a = GetOne();
D d = a.ValueOrDefault(defaultA)
.B.ValueOrDefault(defaultB)
.C.ValueOrDefault(defaultC)
.D.ValueOrDefault(defaultD);
Option is not currently part of C# but I imagine one day will be. You can get an implementation by referencing the F# libraries or you may be able to find an implementation on the web. If you'd like mine, let me know and I'll send it to you.
Well, it depends on exactly what you're doing in the catch. In the above case, it appears that you want to call doSomething() if it's available, but if it isn't you don't care. In this case I would say that trapping the specific exception you're after is just as acceptable as a verbose check to ensure you won't throw one to begin with. There are many "null-safe" methods and extensions that use try-catch in a very similar manner to what you propose; "ValueOrDefault"-type methods are very powerful wrappers for exactly what's been done with the try-catch, for exactly the reason try-catch was used.
Try/catch is, by definition, a program flow control statement. Therefore, it is expected to be used to "control ordinary program flow"; I think the distinction you are trying to make is that it should not be used to control the "happy path" of normal error-free logic flow. Even then I might disagree; there are methods in the .NET Framework and in third-party libraries that either return the desired result or throw an exception. An "exception" is not an "error" until you cannot continue because of it; if there's something else you can try or some default case the situation can boil down to, it can be considered "normal" to receive an exception. So, catch-handle-continue is a perfectly valid use of try-catch, and many uses of exception throwing in the Framework expect you to handle them robustly.
What you want to avoid is using try/catch as a "goto", by throwing exceptions that aren't really exceptions in order to "jump" to the catch statement once some condition is satisfied. This is definitely a hack, and thus bad programming.
The problem with the "catch an exception" approach is that it seems a bit heavy-handed. The exception stack trace should show you where it failed since your method names make it quite clear where you are in the hierarchy but it is not a good way of going about it. Plus how would you recover from the exception and carry on to a good state of your code?
If you must keep this very deep hierarchy then you could use static instances of each object which defines an "empty" state. The best example I can think of which does this is the C# string class which has a static string.Empty field. Then each call of getB(), getC() ... getZ() would return either a real value or the "empty" state, allowing you to chain the method calls.
By making the "empty" state instances static there would only be one of each type in your system. But you would need to consider what an "empty" state looks like for each type in your hierarchy and make sure it doesn't affect any other part of your application inadvertently.
In Python, they encourage the style of "easier to ask forgiveness than permission", which could be applied here to say that it's better to just optimistically try to get to Z without safety checking, and let the exception handler fix a miss. That's easier to code, and it's more performant if the call of Z not being in the call chain is less likely than the case that it will be.
Aside from violating a bunch of OOP good design principles and exposing deeply nested private members, this code also seems vaguely dynamic in nature. That is, you want to call method X but only if X exists on the object, and you want that logic to apply to all objects in a hierarchy of unknown length. And you can't change the design because this is what your XML translation gives you.
Can you change languages then? Statically-typed C# may not be the best choice for what you're doing here. Maybe using Iron Python or some other language that's a little looser on typing will let you more easily manipulate your DOM. Once you've got the data in a stable state, you can pass that off to C# for the rest.
Using exceptions seem a poor fit here. What if one of the getters contained non-trivial logic, and threw a NullPointerException? Your code would swallow that exception without intending to. On a related note, your code samples exhibit different behaviour if parentObject is null.
Also, there really is no need to "telescope":
public Z findZ(A a) {
if (a == null) return null;
B b = a.getB();
if (b == null) return null;
C c = b.getC();
if (c == null) return null;
D d = c.getD();
if (d == null) return null;
return d.getZ();
}
I think you could provide static isValid methods on each class, for example for class A that would be:
public class A {
...
public static boolean isValid (A obj) {
return obj != null && B.isValid(obj.getB());
}
...
}
And so on. Then you would have:
A parentObject;
if (A.isValid(parentObject)) {
// whatever
}
However, although I won't get into you business I must say that such a method chaining does not say anything good about the design; maybe it's a sign of need for refactoring.
I agree with the other answers that this should not need to be done, but if you must here is an option:
You could create an enumerator method once such as:
public IEnumerable<type> GetSubProperties(ClassA A)
{
yield return A;
yield return A.B;
yield return A.B.C;
...
yield return A.B.C...Z;
}
And then use it like:
var subProperties = GetSubProperties(parentObject);
if(SubProperties.All(p => p != null))
{
SubProperties.Last().DoSomething();
}
The enumerator will be lazily evaluated leading to no exceptions.

if-condition vs exception handler

I got the question:
"What do you prefer, exception handling or if-condition?"
for an interview. My answer was that exception handlers are preferred only for exceptional circumstances like a disk permission error on file write. The interviewer seemed to be expecting some other answer. What is the correct answer?
EDIT: Any particular example where exception handling is commonly used when an if-condition would have been more appropriate?
As this question is tagged "C#", we can refer to the .NET Framework Design Guidelines as a good starting point for answering these types of questions. This is the guidance given on MSDN under "Exception Throwing":
Do not use exceptions for normal flow of control, if possible. Except
for system failures and operations with potential race conditions,
framework designers should design APIs so that users can write code
that does not throw exceptions. For example, you can provide a way to
check preconditions before calling a member so that users can write
code that does not throw exceptions.
Here is an example of a bad practice where an exception is handled but can nearly always be avoided:
public int? GetItem(int index)
{
int? value = null;
try
{
value = this.array[index];
}
catch (IndexOutOfRangeException)
{
}
return value;
}
This seems contrived but I see code like this quite often from newer programmers. Assuming proper synchronization around reads and writes to array, this exception can be 100% deterministically avoided. Given that, a better way to write that code would be the following:
public int? GetItem(int index)
{
int? value = null;
// Ensure the index is within range in the first place!
if (index >= 0 && index < this.array.Length)
{
value = this.array[index];
}
return value;
}
There are other cases where you cannot reasonably avoid exceptions and just need to handle them. This is most commonly encountered when you have to deal with external resources such as files or network connections which you could potentially lose access to or contact with at any time. Example from WCF:
public void Close()
{
// Attempt to avoid exception by doing initial state check
if (this.channel.State == CommunicationState.Opened)
{
try
{
// Now we must do a (potentially) remote call;
// this could always throw.
this.channel.Close();
}
catch (CommunicationException)
{
}
catch (TimeoutException)
{
}
}
// If Close failed, we might need to do final cleanup here.
if (this.channel.State == CommunicationState.Faulted)
{
// local cleanup -- never throws (aside from catastrophic situations)
this.channel.Abort();
}
}
Even in the above example, it's good to check that the operation you are going to do at least has a chance of succeeding. So there is still an if () check, followed by the appropriate exception handling logic.
Exception handling is a heavy and expensive operation as far as performance is concerned. If you can avoid catching an exception by using proper if else that can increase application's performance
On the other hand if else block makes more sense to code reader. They are easy to understand and maintain as compared to exceptional try catch block. They describe the program flow in more elegant manner
And finally as you said Exception handling should be for uncertain situations or for exceptional cases it should not be the default choice
Edit
A common bad practise I have seen at some places is this
try
{
string str = "Some String"
int i = Convert.ToInt32(str);
}
catch (Exception ex)
{
MessageBox.Show("Invalid input");
}
Now try catch can be easily avoided in this casing by using if else
string str = "Some String"
int i;
if(!int.TryParse(str, out i))
{
MessageBox.Show("Invalid input");
}
The correct answer is just the one that you gave.
For greater specificity, you should've said something to the effect of "I use if statements wherever possible due to the overhead of catching and throwing exceptions".
I normally prefer to use some special undefined value (e.g. null for objects) to indicate that some computation could not produce a valid result because of invalid input. This means that my code could successfully determine and report that the input data is invalid and no meaningful result can be produced.
I prefer to use an exception when my code cannot complete the requested computation, e.g. if a file containing some required data does not exist, if it cannot connect to a database.
So conceptually:
Undefined result (plus if-condition): program successfully determines that there is no valid output for the given input.
Exception (plus try-catch): program cannot complete computation due to some error in the application not related to the input.
If you know the exact login of the program and knows the errors that can occur then you can write if-else statement or in other case you can leave things to try catch exception handling.

The usefulness of AS operator in C# [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Direct casting vs 'as' operator?
Where could this operator be useful? Instead of writing this:
Asset a = new Asset();
Stock s = a as Stock; // s is null; no exception thrown
if (s != null) Console.WriteLine (s.SharesOwned);
You'd better write something that throws. I saw tons of
(s != null)
in production code and it really becomes ugly. Exceptions are more descriptive and natural in that way. Even conceptually: how can you get no asset if it is not a stock? It should an exception if it is not a stock.
You often have the case where you don’t want an exception to be thrown because, well, the situation isn’t exceptional. You have a frob object which you know can be a Foo, but could also be a Bar. So you want to perform some action only if it’s a Foo.
You try to avoid these situations in designs, and use virtual methods instead. But sometimes there’s just no good way around that.
So rather than taking the roundabout way,
if (frob is Foo) {
((Foo) frob).Frobnicate();
}
you do it directly:
var asFoo = frob as Foo;
if (asFoo != null) {
asFoo.Frobnicate();
}
If nothing else, this is at least more efficient since you only need to test for type equality once (inside the as cast) instead of twice (in the is and in the cast).
As a concrete example, this is very useful when you want to clear all the input boxes in a form. You could use the following code:
foreach (Control c in this.Controls) {
var tb = c As TextBox;
if (tb != null)
tb.Clear();
}
Using an exception here would make no sense.
You'd better write something that throws
Not necessarily. Users don't like seeing things throwing. You should write code that works. And if it doesn't you'd better handle it appropriately by apologizing to the user. The as operator can be useful in situations where for example you would attempt a cast and if this cast doesn't work assign a default value to the variable so that the code continues to work with this default value. It would really depend on the context.
as does an is and if the is returns false assigns null.
sounds like a song but it's the answer and I use it a lot, like in the FindControl methods of ASP.NET:
Button myButton = e.item.FindControl("myControlId") as Button;
this kind of assignment does not crash or throw simply assigns null if FindControl finds something different than a Button. I like this so much....
If Asset is inherited from Stock, then this should be fine. That's the only sort of case where I've seen that work, although you could prolly also use it in the case of interfaces.
Yes, the as operator is useful, and yes, it can be misused.
If you are sure that some variable x is of type T, you should use a regular cast.
T y = (T)x;
If both T1 and T2 are valid types for variable x, you cau use as to check the type and perform the cast in one operation.
What are your requirements?
If the asset is a stock print the number of shares owned.
The as operator is very useful in that case but you will have to check stock != null. That is implied by the requirement.
Print the number of shares owned of a stock. It is an error if another asset is supplied.
Then you should write code that throws an exception.
Exceptions are not designed for flow control, they are, by definition, exceptions to the normal train of events. If it's acceptable for the conversion to fail, use as. If, rather, not being able to cast "a" as a Stock should never happen, you can use simple s=(Stock)a; which will throw it's own exception. You have no control of the exception at this point, though.
The following lets the developer handle the exceptional case much cleaner:
Asset a= new Asset();
Stock s= a as Stock();
if(s == null) {
// Safely exit from call if possible, maybe make calls to logging mechanism or
// other ways of determining why an exception occurred. Also, could throw custom
// Exception if needed with much more detailed info.
} else {
// Continue normal flow
}
You could do:
Asset a= new Asset();
try
{
Stock s= (Stock);
// Continue normal flow
}
catch (InvalidCastException exc)
{
// Safely exit from call if possible, maybe make calls to logging mechanism or
// other ways of determining why an exception occurred. Also, could throw custom
// Exception if needed with much more detailed info.
}
However, that is using the exception as flow control and is costly and bad design.
It depends on your Error Handling policy. I work on code base where we always use casting than using as operator. However, there are some cases where AS operator is very much useful and faster than exception.
For example,
In following case what do you What do you prefer?
public bool Process(int choice)
{
try
{
Thing thing = GetRequiredThing(choice);
SubThing subThing = (SubThing)thing;
}
catch (InvalidCastException ex)
{
// report ex.
return false;
}
}
or
public bool Process(int choice)
{
Thing thing = GetRequiredThing(choice);
SubThing subThing = thing as SubThing;
if (subThing == null)
{
//report error;
return false;
}
}
If is not necessary that you should always use as operator. Take your call.

Categories