My classes that implements an interface, I've got to throw an exception if the class doesn't support values from parent class (done by setting the get property to false/true), so why should I use NotSupportedException, but not NotImplementedException?
When should I use NotImplementedException then? learn.microsoft.com say that it's always better to use NotSupportedException, is it true?
I've found sth like that: https://blog.excastle.com/2004/10/15/notimplementedexception-vs-notsupportedexception/, but it was written in 2004, I think many changed after that. Also, it is written in quite complicated way.
"Not Implemented" implies that it could be implemented it in the future. "Not Supported" makes no such implication as to whether you may implement it or if it even can be implemented.
NotImplementedException is generally used during development as a way to flag to yourself (or Testers, or any other developers) that some aspect hasn't been implemented yet but it is intended to be implemented. You wouldn't normally include this exception in a formal release.
Related
One of my classes has a horrible requirement that resolving one of it's fields requires a service to be brought in by Dependency Injection, which is obviously not possible in a model in the standard Equals() and GetHashCode() calls. (Yes, I'd prefer it not to, bad practice etc, but I'm kind of stuck with it as a business requirement, unfortunately)
I can solve this by creating a Comparer class using IEqualityComparer<T>, but this leaves me with the default Object.Equals() and GetHashCode() being implemented, which may give misleading results when called.
As the presence of the IEqualityComparer is kind of 'hidden' unless you know about it, is it reasonable practice to override the Equals() and GetHashCode to return an exception to say that comparisons should use the Comparer? (Maybe just an Assert so that it only dies in debug/tests)
Throwing an exception like NotSupportedException is better than giving an incorrect answer, although since this is a class, arguably reference equality would suffice as the default, just using the external equality comparer for the custom functionality. But if that is going to cause confusion (in particular with people accidentally using the default API when they should be using the custom one); I wouldn't hesitate. The main problem you'll see is things like Contains checks blowing up, since classes aren't often used as dictionary keys.
As for only doing this in DEBUG builds... well, if it is wrong: it is wrong. If there's a scenario you aren't currently testing but that is used in prod, IMO it is better to become aware of that fact than to not. Although perhaps you might use an environment variable it similar to disable it in case you can't conveniently deploy a fixed build at short notice.
If I'm comparing two mutable objects, I would expect reference equality to be used by default. For records or structs I would expect value equality. For immutable objects I would probably expect value equality, but it depend a bit more on the context.
So I would only throw exceptions or use Debug.Asserts if I was sure reference equality is never the correct thing to use. And in that case I would be extra careful to document and highlight this unexpected behavior.
I would prefer exceptions over a Debug.Assert, since testing is usually done on release builds. And you want to find and fix these kinds of problems, since they most likely indicate a programming bug. There is also Trace.Assert, but I would probably not recommend it since it will make things like automated testing more difficult.
I'm using ASP.NET and I know that I can mark a method as:
Obsolete
Not for future use
But I'm asking if I can mark a method as "Not yet used", that means "I wrote it but actually it is unused, sooner or later someone will using it".
Thanks!
You can throw a NotImplementedException with a appropriate message in your method. This will ensure during runtime that the method is not called.
public void MyMethod(){
throw new NotImplementedException("This will be implemented soon");
}
If you want to use metainformation you can define your own Attribute to decorate your methods. (But I think you can also reuse the ObsoleteAttribute with a special message)
No, you cannot. And it doesn't make much sense to do so.
Visual Studio 2015 does show you the method usage inside your current project, which is an indicator for 'dead' methods:
I assume you want it for a future functionality that currently is not active because is not fully implemented (is the only case I can imagine that make sense).
If you don't want it to be used don't put it in the interface (you should use interfaces) or put it in a distinct one that only you have. You can also use the Obsolete decorator with a "this is not meant to be used yet" message.
If anyone can use it because it's public and released you should not care about how many references it has. Usually you can't know it if the references are from outside your solution. You should not delete such a method because that is a breaking change.
If it's private your IDE should warn you and you can delete it or comment its future usage; add a reference to the functionality it is meant for so you can delete it in case it is closed (someone decides that is not going to be implemented).
This is managed by the NotImplementedException and can be very usefull when implementing interfaces where you know the members you need in the future but don´t want to implement them right now. Any user of the method will get the exception, however if you need a compile-time flag you´d be off by using the Obsolete-attribute together with a meaningul message such as "This method is not yet implemented" and the exception inside.
Just because you can doesn't mean you should....
Why write code that's not yet used?
That's like taking thermal underwear to the Sahara in case of a cold snap, when you're only visiting during the day.
While you can throw a NotImplementedException this won't give you compile time safety - it will just throw this exception on run time.
You can express all of your sorrow about the unused method in the Documentation Comment for this method. Just don't throw any NotImplementedException's or else this method isn't going to be used ever.
This is kinda dumb though, you should remove it if it is not used. As practice shows, most of the 'Not yet, but maybe some day' code is not going to ever be used at all, so it makes perfect sense to remove it. If for some reason you later need the method, you can always check your source control for that.
If you would like to litter your solution even more though, you can always do something stupid like implement your custom [PleaseUseMe]Attribute
In Java, you explicitly define what exceptions are thrown using the "throws" keyword. That way, anyone calling your method knows what to catch.
Is there something in C#? If not, how do I know what exceptions to catch, or how do I let others know what exceptions to catch?
Also, if I am defining an interface, is there a way to say "methodX() should throw this exception on error"?
There is nothing equivalent in C#: The Trouble with Checked Exceptions
Other than documentation, there is no way to declare an interface to say "methodX() should throw this exception on error".
C#/.net does not have checked Exceptions, they proved to be less useful in large scale systems than first thought. In a lot of projects the time to maintain the check exception specs was a lot greater than the debugging time saved by having them.
Checked Exceptions seem like a good ideal until you have methods that can take delegates or calls into object you pass in. Take a simple case, the Sort() method on a list can’t know what exceptions it will throw, as it does not know what exceptions the Compar() method on the objects being sorted will throw.
So the spec for the exceptions a method may throw must be able to include information on how exceptions are populated from pass in objects and delegates. No one knows how to do this!
However there are tools that you check if you are catching all exceptions – see Exception Hunter by Red Gate. I personally don’t see much value in these tool, however if you like checked exceptions you may find them useful. ==> Looks like Exception Hunter wasn't too useful, so Redgate discontinued Exception Hunter a long while ago:
This feature is not available in C#. You can make proper XML documentation (3 slashes ///) and state what exceptions are being thrown.
This will be picked up by the IntelliSense mechanism and will be visible for the users of the class/method before they use it.
C# does not support this. (Not that I know anyway).
What you can do is use Xml Comments so that while calling you methods this data will be shown by intellisense.
As far as I'm aware there is no throws declaration in C# you can document your method indicating that it throws an exception but no forced error handling.
C# doesn't support checked exceptions. The language designers consider checked exceptions in the way java uses them a bad idea.
Some workarounds
Let me cite this medium article: It's almost 2020 and yet... Checked exceptions are still a thing
Among the many reasons why it's a bad idea, putting the checked exceptions in the contract (interfaces):
makes it impossible to change the implementation of an interface with a different one which throws different exceptions
exposes implementation details
a change of the checked exceptions of an API interface, makes it necessary to change the whole chain of interfaces in the call stack
For example, imagine that you are implementing a repository based on SQL Server, so you expose all kind of SQL Server specific exceptions. Then you want to move it to MySQL or Cosmos BD. Of course:
the implementation can't be changed to a new one that need to throw different exceptions. Also related to this, if you have different implementations of the storage, you can't just change them by configuration, but you need to have different compilations of the code for each storage backend
this is the explanation for 1: as the interface showed the implementation details (SQL Server exceptions) know you can't just change it
if you need to make the change, prepare to change the interface at all levels, since the API that uses the database up to the lates consumer in the call stack chain.
The articles cited above includes pointers to many explanations to discourage the use of checked exceptions, included this by the creator of C#: The trouble with checked exceptions
I am continuing with my exam revision.
I have come across the usage of the Base Exception class and I have seen it on exam papers also.
My question is when do you derive from the Base Exception class?
I am of the impression if you want a custom class to throw an exception with more meaningful information, then you can create a custom exception class that contains the exact data that is representative of how your custom class is used and what scenario it is designed to be used for?
Why can't my custom exception class derive from 'ApplicationException' or 'SecurityException' or the base 'Exception' class?
I am of the impression that I should derive from the base Exception class and not the previous two.
My question second is, when would you derive from the other two??? Are there any clear-cut
distinctions as to when you would derive from either one of these three? Assuming there are no others I have I have missed out?
SMALL UPDATE:
This question from transcender pretty much hits the nail on the head.
*Which class should you use to generate an application-specific exception?
Answer: The ApplicationException class*
This is all discussed in the Design Guidelines document.
In our most recent project we used a base exception class. We used it to get the following functionality:
All exceptions needed a number, so defining the property for the number was done in the base class
All exception messages needed to be formatted the same way, with the number, reason and type. This get formmated message was done in the base class.
Our base exception class derives from ApplicationException. This may have been a mistake, there is a lot of discussion about problems with too much depth of inheritance. However, we have not had any problems with this.
One tip for the exam: Read the question very carefully. Good luck.
In general, you want to derive from the Exception class which most closely resembles the type of exception you want to throw. If the trouble is that some Argument or Parameter has been passed which causes a problem, use ArgumentException. If you need some customization with that, inherit from ArgumentException.
In my experience, the only two reasons to use the base Exception are: 1) when you need some custom exception that completely does not fit one of the current exception models or 2) When a method could theoretically throw a number of exceptions, but you've already caught the ones you find most likely to be thrown.
Typically, I don't inherit from exceptions at all. Simply setting the Message property tends to be enough.
Ideally, exceptions should be grouped in a hierarchy such that if code will want to handle several exceptions the same way, they will all be derived from a common base class. If the base throw-able type had been an interface rather than a class, such an ideal might have been somewhat achievable. As it is, however, the single-inheritance limitation for classes severely limits the usefulness of the hierarchy.
The only time an exception hierarchy is apt to be a useful concept is when an implementation of an interface, or a new version of a class, which is documented as throwing certain exceptions wants to allow code to distinguish among more distinct conditions than are reported by those exceptions. In such a scenario, having a method throw exceptions which do not derive from the documented ones would be a breaking change, so one must throw an exception that inherits from the documented one which best describes the previously-unanticipated condition. That's rather ugly, but the exception-handling mechanism doesn't really provide any better alternative. It's rather unfortunate that things like IEnumerator<T>.MoveNext() aren't documented as throwing any exception which would simply mean "Sorry--the system isn't on fire or anything, and I don't know that anybody's changed the collection, but I can neither advance to the next item nor truthfully say the enumeration is complete", but they don't.
Other than the case where one needs to throw an exception that's compatible with existing code, it may be helpful to have the exceptions used by an application or library derive from a common base. Instead of using ApplicationException it should be something like YourApplicationNameException or YourLibraryNameException--something that nothing else is apt to derive from. Something like ApplicationException is bad because code which does a catch ApplicationException will get not only the exceptions which it derived from that type, but also any exceptions which any other libraries derived from it.
If I need to throw an exception from within my application which of the built-in .NET exception classes can I use? Are they all fair game? When should I derive my own?
See Creating and Throwing Exceptions.
On throwing built-in exceptions, it says:
Do not throw System.Exception, System.SystemException, System.NullReferenceException, or System.IndexOutOfRangeException intentionally from your own source code.
and
Do Not Throw General Exceptions
If you throw a general exception type, such as Exception or SystemException in a library or framework, it forces consumers to catch all exceptions, including unknown exceptions that they do not know how to handle.
Instead, either throw a more derived type that already exists in the framework, or create your own type that derives from Exception."
This blog entry also has some useful guidelines.
Also, FxCop code analysis defines a list of "do not raise exceptions" as described here. It recommends:
The following exception types are too general to provide sufficient information to the user:
System.Exception
System.ApplicationException
System.SystemException
The following exception types are reserved and should be thrown only by the common language runtime:
System.ExecutionEngineException
System.IndexOutOfRangeException
System.NullReferenceException
System.OutOfMemoryException
So in theory you can raise any other framework exception type, providing you clearly understand the intent of the exception as described by Microsoft (see MSDN documentation).
Note, these are "guidelines" and as some others have said, there is debate around System.IndexOutOfRangeException (ie many developers throw this exception).
On the subject of System.Exception and System.ApplicationException: The latter was meant to be used as the base class of all custom exceptions. However, this hasn't been enforced consistently from the beginning. Consequently, there's a controversy whether this class should be used at all rather than using System.Exception as the base class for all exceptions.
Whichever way you decide, never throw an instance of these two classes directly. It's actually a pity that they aren't abstact. For what it's worth, always try using the most specific exception possible. If there is none to meet your requirement, feel free to create your own. In this case, however, make sure that your exception has a benefit over existing exceptions. In particular, it should convey its meaning perfectly and provide all the information necessary to handle the situation in a meaningful manner.
Avoid to create stub exceptions that don't do anything meaningful. In the same vein, avoid creating huge exception class hierarchies, they're rarely useful (although I can imagine a situation or two where I would use them … a parser being one of them).
I use the ArgumentException (and its “friends”) regularly.
NotSupportedException and NotImplementedException are also common.
My advice would be to focus on two things:
Scenarios
User expectations
In otherwords, I would sit down and identify:
Under what scenarios do you want to throw exceptions.
In those scenarios, what would the users of your API expect
The answer to #1 is, of course, application specific. The answer to #2 is "what ever similar code they are already familiar with does".
The behavior that comes out of this is:
Under the scenarios that arise in your programs that also arrive inside the
framework, such as arguments being null, out of range, being invalid, methods not
being implemented, or just not supported, then you should use the same exceptions the
framework uses. The people using your APIs are going to expect that they behave that
way (because that's how everything else behaves), and so will be better able to use
your api from the "get go".
For new scenarios that don't exist in the framework, you should go ahead and invent
your own exception classes. I would say that you should prefer Exception as your base
class unless their is some other base exception that provides services you need.
Generally speaking I don't think something like "ApplicationException" will help you
much. When you start defining your own exceptions there are a few things you should
keep in mind though:
a. The primary purpose of an exception is for human communication. They convey
information about something that happened that shouldn't have. They should provide
enough information to identify the cause of a problem and to figure out how to
resolve it.
b. Internal consistency is extremely important. Making your app behave as universally
as possible under similar circumstances will make you API's users more productive.
As far as there being hard and fast rules about what you should and should not do... I wouldn't worry about that stuff. Instead I would just focus on identifying scenarios, finding the existing exception that fits those scenarios, and then carefully desining your own if an existing one doesn't exist.
You can create and throw pretty much any of them, but you generally shouldn't. As an example, the various argument validation exceptions (ArgumentException, ArgumentNullException, ArgumentOutOfRangeException, etc) are suitable for use in application code, but AccessViolationException isn't. ApplicationException is provided as a suitable base class for any custom exception classes you may require.
See this MSDN article for a list of best practices - it refers to handling exceptions, but also contains good advice on creating them...