Why does NotImplementedException exist?
Asked Answered
N

27

65

This really, really urks me, so I hope that someone can give me a reasonable justification for why things are as they are.

NotImplementedException. You are pulling my leg, right?

No, I'm not going to take the cheap stab at this by saying, "hang on, the method is implemented - it throws a NotImplementedException." Yes, that's right, you have to implement the method to throw a NotImplementedException (unlike a pure virtual function call in C++ - now that makes sense!). While that's pretty damn funny, there is a more serious problem in my mind.

I just wonder, in the presence of the NotImplementedException, how can anyone do anything with .Net? Are you expected to wrap every abstract method call with a try catch block to guard against methods that might not be implemented? If you catch such an exception, what the heck are you supposed to do with it??

I see no way to test if a method is actually implemented without calling it. Since calling it may have side effects, I can't do all my checks up-front and then run my algorithm. I have to run my algorithm, catch NotImplementedExceptions and the some how roll back my application to some sane state.

It's crazy. Mad. Insane. So the question is: Why does the NotImplementedException exist?

As a preemptive strike, I do not want anyone to respond with, "because designers need to put this in the auto-generated code." This is horrid. I would rather the auto-generated code not compile until you supply an implementation. For example, the auto generated implementation could be "throw NotImplementedException;" where the NotImplementedException is not defined!

Has anyone ever caught and handled a NotImplementedException? Have you ever left a NotImplementedException in your code? If so, did this represent a time bomb (ie, you accidentally left it there), or a design flaw (the method should not be implemented and will never be called)?

I'm very suspicious of the NotSupportedException also... Not supported? What the? If it's not supported, why is it part of your interface? Can anyone at Microsoft spell improper inheritance? But I might start another question for that if I don't get too abuse for this one.

Additional info:

This is an interesting read on the subject.

There seems to be a strong agreement with Brad Abrams that "NotImplementedException is for functionality that is just not yet implemented, but really should (and will be). Something like what you might start with when you are building a class, get all the methods there throwing NotImplementedException, then flush them out with real code…"

Comments from Jared Parsons are very weak and should probably be ignored: NotImplementedException: Throw this exception when a type does not implement a method for any other reason.

The MSDN is even weaker on the subject, merely stating that, "The exception that is thrown when a requested method or operation is not implemented."

Navvy answered 4/1, 2009 at 9:18 Comment(6)
+1 for raising a valid question about a fuzzy issue that deserves attention.Architecture
Do I get a badge along with the Rant tag?Navvy
I can only guess you have never had to implement a library with a given interface...Uncle
Good guess, but you're not right. I can only guess you don't understand the question.Navvy
@Daniel - there is a more etymological answer, also. In Win32 C API, there was defined the E_NOTIMPL return value. Every such return value was mapped to a .Net exception.Distasteful
@Heath - so your reasoning for the NotImplementedException existing as a system exception is because of sins of our past?Navvy
T
142

There is one situation I find it useful: TDD.

I write my tests, then I create stubs so the tests compile. Those stubs do nothing but throw new NotImplementedException();. This way the tests will fail by default, no matter what. If I used some dummy return value, it might generate false positives. Now that all tests compile and fail because there is no implementation, I tackle those stubs.

Since I never use a NotImplementedException in any other situation, no NotImplementedException will ever pass onto release code, since it will always make some test fail.

You don't need to catch it all over the place. Good APIs document the exceptions thrown. Those are the ones you should look for.

EDIT: I wrote an FxCop rule to find them.

This is the code:

using System;
using Microsoft.FxCop.Sdk;

/// <summary>
/// An FxCop rule to ensure no <see cref="NotImplementedException"/> is
/// left behind on production code.
/// </summary>
internal class DoNotRaiseNotImplementedException : BaseIntrospectionRule
{
    private TypeNode _notImplementedException;
    private Member _currentMember;

    public DoNotRaiseNotImplementedException()
        : base("DoNotRaiseNotImplementedException",
               // The following string must be the assembly name (here
               // Bevonn.CodeAnalysis) followed by a dot and then the
               // metadata file name without the xml extension (here
               // DesignRules). See the note at the end for more details.
               "Bevonn.CodeAnalysis.DesignRules",
               typeof (DoNotRaiseNotImplementedException).Assembly) { }

    public override void BeforeAnalysis()
    {
        base.BeforeAnalysis();
        _notImplementedException = FrameworkAssemblies.Mscorlib.GetType(
            Identifier.For("System"),
            Identifier.For("NotImplementedException"));
    }

    public override ProblemCollection Check(Member member)
    {
        var method = member as Method;
        if (method != null)
        {
            _currentMember = member;
            VisitStatements(method.Body.Statements);
        }
        return Problems;
    }

    public override void VisitThrow(ThrowNode throwInstruction)
    {
        if (throwInstruction.Expression != null &&
            throwInstruction.Expression.Type.IsAssignableTo(_notImplementedException))
        {
            var problem = new Problem(
                GetResolution(),
                throwInstruction.SourceContext,
                _currentMember.Name.Name);
            Problems.Add(problem);
        }
    }
}

And this is the rule metadata:

<?xml version="1.0" encoding="utf-8" ?>
<Rules FriendlyName="Bevonn Design Rules">
  <Rule TypeName="DoNotRaiseNotImplementedException" Category="Bevonn.Design" CheckId="BCA0001">
    <Name>Do not raise NotImplementedException</Name>
    <Description>NotImplementedException should not be used in production code.</Description>
    <Url>https://mcmap.net/q/65439/-why-does-notimplementedexception-exist</Url>
    <Resolution>Implement the method or property accessor.</Resolution>
    <MessageLevel Certainty="100">CriticalError</MessageLevel>
    <Email></Email>
    <FixCategories>NonBreaking</FixCategories>
    <Owner></Owner>
  </Rule>
</Rules>

To build this you need to:

  • reference Microsoft.FxCop.Sdk.dll and Microsoft.Cci.dll

  • Put the metadata in a file called DesignRules.xml and add it as an embedded resource to your assembly

  • Name your assembly Bevonn.CodeAnalysis. If you want to use different names for either the metadata or the assembly files, make sure you change the second parameter to the base constructor accordingly.

Then simply add the resulting assembly to your FxCop rules and take those damned exceptions out of your precious code. There are some corner cases where it won't report a NotImplementedException when one is thrown but I really think you are hopeless if you're actually writing such cthulhian code. For normal uses, i.e. throw new NotImplementedException();, it works, and that is all that matters.

Tetrastich answered 4/1, 2009 at 10:34 Comment(16)
I agree completely. Throwing this in any other setting is like having an "Under Construction" sign on your web page.Compotation
Nice. However, Why is NotImplementedException part of the .net core? I'd prefer this concept to be vendor specific and I would conditionally compile out my NotImplementedException in all public release builds. This is not a concept for the .net core.Navvy
What causes damage in it being there? For me, it saves me the time of writing a dumb exception. And with my approach, I don't need to compile it out. I can guarantee it is never used in release code. And it sure doesn't make the framework much larger...Tetrastich
Ok, I give it to you that it being an exception may not be the best solution. I would prefer the aspect idea.Tetrastich
@Martinho: yeah baby, you're coming round.Navvy
@Martinho: meant to add that the damage caused by it being in the core is that you can not remove it from your build so it is possible to ship a product or a patch that still has these nasty buggers in it. I prefer a technique that makes it impossible to make such a mistake.Navvy
@Daniel: You remove it from your code by implementing the feature. I don't see where the confusion lies (forgive me if that sounds snarky, it isn't meant to be.)Architecture
@Daniel: Combine the NotImplemented feature with TDD to ensure that a feature gets implemented; once the feature is implemented, remove the exception. It never gets to release code. A NotSupportedException is for providers, and is well documented, and SHOULD be caught by clients.Architecture
@Mike: if it's never used in released code, why is it in the .net core? If it never gets into released code, it need not be documented nor caught by anyone. PS: your tone is just fine with me! It's hard to remain all soft and squishy in 300 chars.Navvy
@Daniell Paull It's really nice to have this in the .net core because it presents a standardised, unformed way that I can do "find usages" in my IDE to identify unfinished stuff.Aeolus
@krosenvold: An IDE feature dictating platform design? Sounds backwards to me.Navvy
@krosenvold: You could do "find usages" with XYZException. It would work the same. You just would need to write XYZException yourself.Tetrastich
I have accepted this as the "right" answer as I agree with this use of the exception. It's use still seems dangerous to me, but with the right checks and balances, this usage is reasonable.Navvy
I love the idea of using FxCop to double check that no NotImplementedExceptions remain. I've used it against one my projects and found one minor error. In VisitThrow you need to check that throwInstruction.Expression is not null. This occurs whenever someone rethrows via a bare "throw;" instruction. Other than that, great thanks!Cherrylchersonese
+1 For cthulhian code. Best adjective I've ever heard for bad code.Sophocles
Sadly, I am elbow deep in Cthulhian code lately. No NotImplementedExceptions, that I know of - but I would much prefer a function that doesn't exist to one that exists only to give tentacle hugs.Hydromancy
E
40

It's there to support a fairly common use case, a working but only partially completed API. Say I want to developers to test and evaluate my API - WashDishes() works, at least on my machine, but I haven't gotten around yet to coding up DryDishes(), let alone PutAwayDishes(). Rather than silently failing, or giving some cryptic error message, I can be quite clear about why DryDishes() doesn't work - I haven't implemented it yet.

Its sister exception NotSupportedException make sense mostly for provider models. Many dishwashers have a drying function, so belongs in the interface, but my discount dishwasher doesn't support it. I can let that be known via the NotSupportedException

Elisha answered 4/1, 2009 at 9:32 Comment(10)
But why is it a system exception? Why cant you throw your own exception? Why has MS made this part of the .net core? As for the dishwasher without the dry function - why does it have a dry method? Improper inheritance.Navvy
Why would you rather write your exception for such a situation?Tetrastich
because then I can remove it completely from release builds to avoid accidentally leaving one in the code.Navvy
But you still have the freedom to do so; you aren't compelled to use NotSupportedException. Nonetheless, the situation arises so frequently that a standard class exists for it in the Framework, as it should.Architecture
Correction: NotImplementedException, although, NotSupportedException is equally applicable.Architecture
You have no such freedom when all the standard tools auto generate code that has stubs that throw the NotImplementedException! You're also stuck if third party assemblies use it.Navvy
You can use "find usages" in your IDE for notimplementedexception. That's whyAeolus
@krosenvold: That's why? An IDE feature dictating platform design? Sounds backwards to me.Navvy
@Daniel Paull: NotImplementedException is part of the core because people are lazy, if it didn't exist they would use Exception, NotSupportedException, InvalidOperationException, or some other exception instead.Flagellate
It's also part of the core because it's useful for code generators that require you to implement something (like visual studios automatic interface implementation). Also if it accidentally gets into production, that means that you accidentally forgot to implement something, that you haven't tested against that code path and that you have a bug.Salish
A
28

I'll summarize my views on this in one place, since they're scattered throughout a few comments:

  1. You use NotImplementedException to indicate that an interface member isn't yet implemented, but will be. You combine this with automated unit testing or QA testing to identify features which still need to be implemented.

  2. Once the feature is implemented, you remove the NotImplementedException. New unit tests are written for the feature to ensure that it works properly.

  3. NotSupportedException is generally used for providers that don't support features that don't make sense for specific types. In those cases, the specific types throw the exception, the clients catch them and handle them as appropriate.

  4. The reason that both NotImplementedException and NotSupportedException exist in the Framework is simple: the situations that lead to them are common, so it makes sense to define them in the Framework, so that developers don't have to keep redefining them. Also, it makes it easy for clients to know which exception to catch (especially in the context of a unit test). If you have to define your own exception, they have to figure out which exception to catch, which is at the very least a counter-productive time sink, and frequently incorrect.

Architecture answered 4/1, 2009 at 12:2 Comment(1)
You admit that the NotImplementedException will be removed - if this is the case, there is no need for it in the .net core. It's your own private concern of your own private development process.Navvy
L
19

Why does the NotImplementedException exist?

NotImplementedException is a great way to say that something is not ready yet. Why it's not ready is a separate question for method's authors. In production code you're unlikely to catch this exception, but if you did you can immediately see what happened and it's much better than trying to figure out why methods was called but nothing happened or even worse - receive some "temporary" result and get "funny" side effects.

Is NotImplementedException the C# equivalent of Java's UnsupportedOperationException?

No, .NET has NotSupportedException

I have to run my algorithm, catch NotImplementedExceptions and the some how roll back my application to some sane state

Good API has XML methods documentation that describes possible exceptions.

I'm very suspicious of the NotSupportedException also... Not supported? What the? If it's not supported, why is it part of your interface?

There can be millions reasons. For example you can introduce new version of API and don't want to/can't support old methods. Again, it is much better to see descriptive exception rather then digging into documentation or debugging 3rd party code.

Lexis answered 4/1, 2009 at 9:36 Comment(8)
Thank you aku - API support - deprecating methods might be a reasonable reason for this exception. Thouggh I'd prefer to see a DeprecatedMethodException.Navvy
There is an Obsolete attribute, I wish we have something like NotImplemented attribute to get compile-time warnings.Lexis
@aku: excellent comment - this addresses the issue of not being able to tell if a method is actually implemented before calling it (not that one should ever have to do that).Navvy
Even though I use the exception a lot (see my answer), I would rather like that attribute thingy, especially if I could turn it into an aspect that throws an exception(NotImplemented being my first choice, for clarity).Tetrastich
Java UnsupportedOperationException could also be .NET InvalidOperationException.Flagellate
An NotImplemented attribute would only work if the class is directly (and not calling the method using an interface)Flagellate
.Net's InvalidOperationException corresponds more closely to Java's IllegalStateException.Brad
@Lexis - Yes, mate. Thats what they have in Java. Java-devs can call a static method "Trace" like this NotImplementedException.Trace("warning!! not implemented!!"); I envy javistsDreadful
F
12

The main use for a NotImplementedException exception is in generated stub code: that way you don't forget to implement it!! For example, Visual Studio will explicitly implement an interface's methods/properties with the body throwing a NotImplementedException.

Freudberg answered 4/1, 2009 at 9:30 Comment(6)
@Daniel Paull: the exception that's thrown!Freudberg
@Mitch: Assuming you call the code. Not everyone uses code coverage tools, so this could be missed quite easily.Navvy
You better want the method to throw an exception than to simply "do nothing" because it's not implemented. That way you have the chance to find and fix the issue.Carchemish
@Daniel Paull: and an assertion suffers from the same problem.Freudberg
@Mitch: assertions are a tool to test conditions that can not (by design) occur in your system - any assertion that is tripped indicates a programming error. Exceptions indicate runtime circumstances that do not (necessarily) indicate programming errors. Apples and oranges.Navvy
What you can do is search all your code for NotImplementedExceptions and make sure you find zero when you release.Demonetize
E
8

Re NotImplementedException - this serves a few uses; it provides a single exception that (for example) your unit tests can lock onto for incomplete work. But also, it really does do what is says: this simply isn't there (yet). For example, "mono" throws this all over the place for methods that exist in the MS libs, but haven't been written yet.

Re NotSupportedException - not everything is available. For example, many interfaces support a pair "can you do this?" / "do this". If the "can you do this?" returns false, it is perfectly reasonable for the "do this" to throw NotSupportedException. Examples might be IBindingList.SupportsSearching / IBindingList.Find() etc.

Enarthrosis answered 4/1, 2009 at 9:32 Comment(2)
Ok, so there should be a Mone.NotImplementedException - why is it part of the .net core? If you avoid improper inheritance, an object is what it says it is, so the "can you do this?" / "do this" are redundant.Navvy
It sure smells like improper inheritance.Navvy
U
6

Most developers at Microsoft are familiar with design patterns in which a NotImplementedException is appropriate. It's fairly common actually.

A good example is a Composite Pattern, where many objects can be treated as a single instance of an object. A component is used as a base abstract class for (properly) inherited leaf classes. For example, a File and Directory class may inherit from the same abstract base class, because they are very similar types. This way, they can be treated as a single object (which makes sense when you think about what files and directories are - in Unix for example, everything is a file).

So in this example, there would be a GetFiles() method for the Directory class, however, the File class would not implement this method, because it doesn't make sense to do so. Instead, you get a NotImplementedException , because a File does not have children the way a Directory does.

Note that this is not limited to .NET - you'll come across this pattern in many OO languages and platforms.

Upend answered 4/1, 2009 at 9:34 Comment(8)
Why would the File not return an empty list when asked for it's children through the abstract interface?Navvy
As an application developer, I certainly wouldn't expect it to. How about a method called AddFile() that is implemented by the Directory class - what would you expect if you called this on the File class? I would expect an exception. This behavior should be consistent in a good API.Upend
A File is not a directory - improper inheritance. Mutable abstract interfaces need to be designed carefully.Navvy
-1, if the subclasses can't implement GetFiles then the hierarchy is wrong, en.wikipedia.org/wiki/Liskov_substitution_principlePyszka
File doesn't inherit from Directory in my example; you misread it. Sorry, this does not violate the Liskov Substitution principle. The base abstract component class throws the exception. It is up to the subclasses to implement those methods appropriately.Upend
Poor analogy perhaps, but Jarvis's point is correct. I prefer to view the composite methods which throw notimplemented as could-do, but does-not. You'll often see this with virtual methods.Pyrone
This is contrary to the prevalent view in other answers that no production code should ever throw NotImplementedExceptions. I have trouble understanding what "could-do, but does-not" means. If you said, "will-do, but does-not yet", then I'm happy again - see the accepted answer.Navvy
Microsoft uses NotImplementedException very extensively in the Microsoft Office Object Models. As a PowerPoint programmer, it sometimes drives me crazy! For example, when I try to call certain methods or Properties of a Shape or AnimationSettings, they may work fine or may throw NotImplementedException depending on the situation. I wish there was a way to check a method for NotImplementedException without actually causing it.Tatiania
P
5

Why do you feel the need to catch every possible exception? Do you wrap every method call with catch (NullReferenceException ex) too?

Stub code throwing NotImplementedException is a placeholder, if it makes it to release it should be bug just like NullReferenceException.

Pyszka answered 4/1, 2009 at 10:39 Comment(3)
If used as merely as a placeholder, Why is NotImplementedException part of the .net core? I'd prefer this concept to be vendor specific and I would conditionally compile out my NotImplementedException in all public release builds. This is not a concept for the .net core.Navvy
@Daniel, I guess we have different opinions about it, but I would definitely not compile out the exceptions in release builds, just like I wouldn't catch a NullReferenceException - I'd fix the bug.Pyszka
@orip: I think you misread. Compile out the NotImplementedException class, not the places it's used. This would force any stray uses of the NotImplementedException to become compile errors.Navvy
W
5

I think there are many reasons why MS added NotImplementedException to the framework:

  • As a convenience; since many developers will need it during development, why should everybody have to roll their own?
  • So that tools can rely on its presence; for example, Visual Studio's "Implement Interface" command generate method stubs that throw NotImplementedException. If it were not in the framework, this would not be possible, or at least rather awkward (for example, it could generate code that doesn't compile until you add your own NotImplementedException)
  • To encourage a consistent "standard practice"

Frankodwyer thinks of NotImplementedException as a potential timebomb. I would say that any unfinished code is a timebomb, but NotImplementedException is much easier to disarm than the alternatives. For example, you could have your build server scan the source code for all uses of this class, and report them as warnings. If you want to be really ban it, you could even add a pre-commit hook to your source-control system that prevents checkin of such code.

Sure, if you roll your own NotImplementedException, you can remove it from the final build to make sure that no time bombs are left. But this will only work if you use your own implementation consistently in the entire team, and you must make sure that you don't forget to remove it before you release. Also, you might find that you can't remove it; maybe there are a few acceptable uses, for example in testing code that is not shipped to customers.

Wollongong answered 4/1, 2009 at 12:0 Comment(3)
Why not have a "Microsoft.Development.Support" or similar assembly that has useful classes and utilities (including NotImplementedException). The intent is to reference that assembly in dev builds, but not in released code?Navvy
This would require adding the Microsoft.Development.Support assembly reference to each project that is using it, creating another inconvenience and hurdle for tools.Wollongong
And the problem with this is? I'd rather have my system correct that have a minor inconvenience for my developers. It would be more convenient to do way with DLLs, but the benefit justifies the cost (by cost I mean effort and complexity).Navvy
G
5

There is really no reason to actually catch a NotImplementedException. When hit, it should kill your app, and do so very painfully. The only way to fix it is not by catching it, but changing your source code (either implementing the called method, or changing the calling code).

Grose answered 4/1, 2009 at 23:15 Comment(4)
This is a very strange answer. If no one is ever meant to catch the exception, why would one ever throw it and why is it part of the .Net core? NOTE: just because you throw an exception doesn't mean it won't be caught. Why not just Assert(false) in both debug and release builds?Navvy
What would you do in the catch clause? Specifically for NotImplementedException?Grose
If I had my way, I would never throw nor catch the NotImplementedException. I am trying to find a case for it being part of the core library.Navvy
There are many other exceptions you're not supposed to catch either (StackOverflowException, OutOfMemoryException)Grose
R
4

Two reasons:

  1. Methods are stubbed out during development, and throw the exception to remind the developers that their code writing is not finished.

  2. Implementing a subclass interface that, by design, does not implement one or more methods of the inherited base class or interface. (Some interfaces are just too general.)

Recapitulate answered 13/1, 2010 at 23:35 Comment(3)
If you're working in interfaces that are "too general" for a class you're writing, you should probably consider an interface that only has the methods you actually want. If IFooBar has three methods and I have an instance of IFooBar, those methods better be implemented (or at least only throw contractually-defined exceptions). I'd say that 95% of the time or more throwing a NotImplementedException() would be a violation of the Liskov Substitution Principle.Tampon
Yes, but sometimes you don't have a choice, like when you're using the standard .NET library. Consider some of the "optional" methods in the iterator and I/O streams classes.Recapitulate
@S. DePouw: It might not violate the Liskov Substitution Principle if there is another way to determine if the method should be called at runtime, like a CanXXX() test that tells you that you can call XXX(). However, I am highly suspicious of these sort of interfaces as they smell like improper inhertance - as does (2) in this answer.Navvy
N
3

This sounds like a potential minefield to me. In the distant past I once worked on a legacy network system that had been running nonstop for years and which fell over one day. When we tracked the problem down, we found some code that had clearly not been finished and which could never have worked - literally, like the programmer got interrupted during coding it. It was obvious that this particular code path had never been taken before.

Murphy's law says that something similar is just begging to happen in the case of NotImplementedException. Granted in these days of TDD etc, it should be picked up before release, and at least you can grep code for that exception before release, but still.

When testing it is difficult to guarantee coverage of every case, and this sounds like it makes your job harder by making run time issues of what could have been compile time issues. (I think a similar sort of 'technical debt' comes with systems that rely heavily on 'duck typing', while I acknowledge they are very useful).

Narcotism answered 4/1, 2009 at 10:24 Comment(0)
C
3

You need this exception for COM interop. It's E_NOTIMPL. The linked blog also shows other reasons

Cornejo answered 5/1, 2009 at 15:53 Comment(1)
If the only valid use is to map to COM's E_NOTIMPL, then this exception should surely be in the interop namespace. What other valid uses are sited on that blog? The argument that it is to indicate a transient state of development is poor; use your own exception for that.Navvy
C
3

Throwing NotImplementedException is the most logical way for the IDE to to generate compiling stub code. Like when you extend the interface and get Visual Studio to stub it for you.

If you did a bit of C++/COM, that existed there as well, except it was known as E_NOTIMPL.

There is a valid use case for it. If you are working on a particular method of an interface you want you code to compile so you can debug and test it. According to your logic you would need to remove the method off the interface and comment out non-compiling stub code. This is a very fundamentalist approach and whilst it has merit, not everyone will or should adhere to that. Besides, most of the time you want the interface to be complete.

Having a NotImplementedException nicely identifies which methods are not ready yet, at the end of the day it's as easy as pressing Ctrl+Shift+F to find them all, I am also sure that static code analysis tools will pick it up too.

You are not meant to ship code that has NotImplementedException exception. If you think that by not using it you can make your code better, go forth, but there are more productive things you can do to improve the source quality.

Collide answered 13/1, 2010 at 22:59 Comment(3)
"According to your logic you would need to remove the method off the interface and comment out non-compiling stub code." Let's not put words in my mouth - I would never suggest you do this. I agree that you will have unimplemented stubs during developent. But those stubs could throw your own exception. I just don't see why the NotImplementedException should exist as part of the .Net core libraries.Navvy
Well in that case you did a common StackOverflow and didn't ask what you really wanted to ask. Your own answer answers your question quite succintly, but I, and I am sure, others read your question as "You shouldn't be throwing exceptions for unimplemented methods."Collide
Why throw your own exceptions when there is a standard for it? Reeinventing the wheel is one of the main reasons why working in "our" industry is sometimes such a pain (NIH syndrome...) There are some places where you will need stubs, and throwing a standardized exception lets you track these easily with tools like "grep" for example. I also use NIE's a lot with TDD as well. There are a lot of places where they make sense. Just leaving off the stub is sometimes even more dangerous, I like to spam my code with "//TODO:"s because once its written down I cant forget it.Elongation
F
2

NotImplementedException

The exception is thrown when a requested method or operation is not implemented.

Making this a single exception defined in the .NET core makes it easier to find and eradicate them. If every developer should create their own ACME.EmaNymton.NotImplementedException it would be harder to find all of them.

NotSupportedException

The exception is thrown when an invoked method is not supported.

For instance when there is an attempt to read, seek, or write to a stream that does not support the invoked functionality.

For instance generated iterators (using yield keyword) is-a IEnumerator, but the IEnumerator.Reset method throws NotSupportedException.

Flagellate answered 4/1, 2009 at 11:29 Comment(11)
"makes it easier to find and eradicate them" - easier? That's your reason? Not because it's the right way to do it, but because it's the easy way to do it. Nice one man.Navvy
Why does a stream than does not support random access have a seek method? Lets not hide behind Microsoft's poor stream interface design.Navvy
I'm now scared of calling Reset() an any enumerator.Navvy
Sure an INotResetEnumerator would perhaps be better, which the IEnumerator derives from. But the leads to too many classes.Flagellate
It would be interesting to design it properly. I disagree that it would lead to too many interfaces.Navvy
It all depends on the granularity, you could have IListMutable (which contains Add, Clear, Insert, Remove, RemoveAt) and IListImmutable (Contains, CopyTo, GetEnumerator, IndexOf). MyList : IListMutable, IListImmutable { /*impl*/ }Flagellate
But what if you want an add only and readonly list? MyList : IListAdd, IListInsert, IListImmutable { /*impl*/ } and let IListMutable : IListAdd, IListClear, IListInsert, IListRemove, IListRemoveAtFlagellate
The interface for mutating abstract types is always going to be tricky and should be designed very carefully. Dare we ask if a square is-a rectangle?Navvy
It sounds like you're suggesting that the designer of any interface should always be able to guess all of the uses to which the interface might be put, in the manner of an oracle. Sure, within a single project this might be possible; in general I rather think not.Suppositious
@zacharyrsnow: If one follows sound object oriented design principals then the interfaces will be intuitive and serve a clear purpose. Since the purpose is clear, no super powers (like an oracle) is required during desing. So, in general I rather think so...Navvy
@dalle: The proper design would have been to have IEnumerable not provide reset, but provide fairly loose guarantees about enumeration behavior when the collection is updated (throwing an exception would be an option, but not required, if all items that exist throughout the enumeration are returned exactly once, etc.); IMultipassEnumerable would add Reset, FastCount, and Count (FastCount would return at its option either -1 or a correct count; it could be used to pre-allocate space for a list if the size of the collection was known before it was entirely enumerated).Reprobate
W
2

From ECMA-335, the CLI specification, specificialy the CLI Library Types, System.NotImplementedException, remarks section:

"A number of the types and constructs, specified elsewhere in this Standard, are not required of CLI implementations that conform only to the Kernel Profile. For example, the floating-point feature set consists of the floating-point data types System.Single and System.Double. If support for these is omitted from an implementation, any attempt to reference a signature that includes the floating-point data types results in an exception of type System.NotImplementedException."

So, the exception is intended for implementations that implement only minimal conformance profiles. The minimum required profile is the Kernel Profile (see ECMA-335 4th edition - Partition IV, section 3), which includes the BCL, which is why the exception is included in the "core API", and not in some other location.

Using the exception to denote stubbed methods, or for designer generated methods lacking implementation is to misunderstand the intent of the exception.

As to why this information is NOT included in the MSDN documentation for MS's implementation of the CLI is beyond me.

Wnw answered 30/7, 2009 at 15:39 Comment(0)
N
2

I can't vouch for NotImplementedException (I mostly agree with your view) but I've used NotSupportedException extensively in the core library we use at work. The DatabaseController, for example, allows you to create a database of any supported type then use the DatabaseController class throughout the rest of your code without caring too much about the type of database underneath. Fairly basic stuff, right? Where NotSupportedException comes in handy (and where I would have used my own implementation if one didn't already exist) is two main instances:

1) Migrating an application to a different database It's often argued this rarely, if ever, happens or is needed. Bullsh*t. Get out more.

2) Same database, different driver Most recent example of this was when a client who uses an Access-backed application upgraded from WinXP to Win7 x64. Being no 64-bit JET driver, their IT guy installed the AccessDatabaseEngine instead. When our app crashed, we could easily see from the log it was DB.Connect crashing with NotSupportedException - which we were quickly able to address. Another recent example was one of our programmers trying to use transactions on an Access database. Even though Access supports transactions, our library doesn't support Access transactions (for reasons outside the scope of this article). NotSupportedException, it's your time to shine!

3) Generic functions I can't think of a concise "from experience" example here but if you think about something like a function that adds an attachment to an email, you want it to be able to take a few common files like JPEGs, anything derived from various stream classes, and virtually anything which has a ".ToString" method. For the latter part, you certainly can't account for every possible type so you make it generic. When a user passes OurCrazyDataTypeForContainingProprietarySpreadsheetData, use reflection to test for the presence of a ToString method and return NotSupportedException to indicate lack of support for said data types that don't support ToString.

NotSupportedException isn't by any means a crucial feature but it's something I find myself using a lot more as I work on larger projects.

Northington answered 13/1, 2010 at 22:46 Comment(0)
T
2

Lets say you have this method in your production code

public void DoSomething()

Which one would you take if you want to leave it later to be finished?

public void DoSomething()
{
}

or

public void DoSomething()
{
    throw new NotImplementedException();
}

I would certainly take the second. Coupled with Elmah or whatever error logging mechanism you have (implemented as an aspect across your entire application). Together with log/exception filtering to trigger for critial error email notification when one is caught.

The argument that NotImplementedException == unfinished isn't correct either. (1) Catching of unimplemented methods should be left to unit tests/ integration tests. If you have 100% coverage (which you should now do, with so many many mock/stub/code generation tools) with no NotImplementedException, what are your worries? (2) Code generation. Plain simple. Again, if I generate the code, and only use half of the generated code, why wouldn't I have NotImplementedException in the rest of the generated stub?

It's like saying code shouldn't compile unless every nullable input should be checked/handled for null. (AKA the trillion dollar mistake, if not more). Language should be flexible, while tests/contracts should be solid.

Taveras answered 23/8, 2011 at 8:3 Comment(1)
Worse, how about something like Point ComputeLocation() { return default(Point); }. There are many cases where the correct behavior for a method with no return value is simply do nothing (e.g. many classes implement IDisposable.Dispose() as a no-op), but having a method that returns a structure type return a default instance as though it were a real value seems really dubious.Reprobate
M
1

NotImplementedException is thrown for some method of .NET (see the parser C# in Code DOM which is not implemented, but the method exist !) You can verify with this method Microsoft.CSharp.CSharpCodeProvider.Parse

Measure answered 4/1, 2009 at 9:35 Comment(3)
I once went nuts when I realized had to write my own parser. That's really bad.Tetrastich
Not just "bad", but inexcusable.Navvy
have a look at this list: blogs.msdn.com/brada/archive/2004/07/29/201354.aspx#203896Navvy
B
1

Rarely I do use it for interface fixing. Assume that you've an interface that you need to comply but certain method will be never called by anyone, so just stick a NotImplementedException and if someone calls it they will know they are doing something wrong.

Bitthia answered 4/1, 2009 at 10:38 Comment(7)
An interface method that can never be called? What the heck?Navvy
If you don't implement the whole interface, don't implement it. With that methodology, you should use languages that can duck type, like Python or even c#4 :(.Tetrastich
So you got 10 classes implements an interface but one of them or couple of them has got extra methods that you need to call. What's the way to do it? I do implement the interface with an extra method and call it if the type matches. What's you solution? 10 separate classes?Bitthia
@Slough: give me an example where this is the case and I'll fix your design free of charge.Navvy
IDataReader has a ton of methods on it. I've had to implement it interface before knowing that I'm only going to need three of the methods. The interface is in the .net framework. I can't change it. I'm also passing it to a framework class I can't change. It's a bad interface, but I'm stuck with it.Brahmanism
@Mike: I feel your pain, and this scenario may be valid as your hand has been forced. So MS included this bad exception to support their poor interface and framework design. Reasonable argument. I think that in this case, two wrongs just made things worse.Navvy
The case of IDataReader and friends indicates the use. Most instances use only a subset of its methods. When constructing the interface as a wrapper, the unused stubs need to do something. This is about the most sane thing to do.Dehisce
M
1

They are both hacks for two common problems.

NotImplementedException is a workaround for developers who are architecture astronauts and like to write down the API first, code later. Obviously, since this is not a incremental process, you can't implement all at once and therefore you want to pretend you are semi-done by throwing NotImplementedException.

NotSupportedException is a hack around the limitation of the type systems like those found in C# and Java. In these type systems, you say that a Rectangle 'is a' Shape iff Rectangle inherits all of Shapes characteristics (incl. member functions + variables). However, in practice, this is not true. For example, a Square is a Rectangle, but a Square is a restriction of a Rectangle, not a generalization.

So when you want to inherit and restrict the behavior of the parent class, you throw NotSupported on methods which do not make sense for the restriction.

Mittiemittimus answered 4/1, 2009 at 15:24 Comment(3)
There is no reason why the architecture astronaut can't design a sensible interface, other than - they suck at design and are not capable of doing their job. The Architect (yuk) should not have the last say in the API design; developers should be consulted and sign off prior it implementation.Navvy
When you want to inherit and restrict the behavior of the parent class, you're breaking the base class/interface invariants. Unless the base class/interface's contract explicitly says implementations may not support all features (probably with the CanDo/Do() pattern), don't do this. You'll most likely break client code. If you have to break Rectangle's contract to create a Square class, a Square is not a (i.e. does not inherit from) Rectangle. I know it's easy to see inheritance as "is a", but sometimes that can be a really bad metaphor.Tetrastich
@Mittiemittimus - I suggest you do some reading around. The "A square is a special rectangle" is the ubiquitous example showing where people get inheritance wrong.Complex
R
0

What about prototypes or unfinished projects?

I don't think this is a really bad idea to use an exception (although I use a messagebox in that case).

Refund answered 4/1, 2009 at 9:24 Comment(5)
So, it should never make it into production code? Then why is it part of the .net core? If you want this concept, then just "throw new Object();" with a comment stating that the method is pending implementation.Navvy
BTW - I'll give you +1 because you'd prefer to use something other than the exception. Personally I'd drop in an assert( false ) and a dummy return value, assuming I need the code to compile.Navvy
@Daniel Paull : but surely that is more dangerous, because the assertions won't be compiled into Release code?...Freudberg
@Daniel Paull: in fact you've jogged my memory, and I can recall a situation where exactly that happened...Freudberg
If you program by contract, test your system and prove correctness, asserts are just dandy. The alternative just seems like a wing and a prayer. I am a massive advocate of asserts and getting your design right. It shouldn't be luck that makes your system work.Navvy
P
0

Well, I somewhat agree. If an interface has been made in such a way that not all class can implement all bits of it, it should've been broken down in my opinion.

If IList can or cannot be modified, it should've been broken down into two, one for the unmodifiable part (getters, lookup, etc.), and one for the modifiable part (setters, add, remove, etc.).

Propane answered 4/1, 2009 at 9:38 Comment(0)
P
0

I have a few NotImplementedExceptions in my code. Often times it comes from part of an interface or abstract class. Some methods I feel I may need in the future, they make sense as being part of the class, but I just don't want to take the time to add unless I actually need it. For example, I have an interface for all the individual kinds of stats in my game. One of those kinds are a ModStat, which is the sum of the base stat plus all the modifiers (ie weapons, armor, spells). My stat interface has an OnChanged event, but my ModStat works by calculating the sum of all stats it references each time it is called. So instead of having the overhead of a ton of ModStat.OnChange events being raised every time a stat changes, I just have a NotImplementedException thrown if anyone tries to add/remove a listener to OnChange.

.NET languages are all about productivity, so why spend your time coding something you won't even use?

Popcorn answered 4/1, 2009 at 11:5 Comment(4)
"so why spend your time coding something you won't even use?" Interesting - it seems that you have implemented stubs that you may never actually implement. Follow your own advice and you wont need the NotImplementedException!Navvy
A Daniel said, you should not write stubs for no use. If you "may" need them in the future, write them in the future. Most of the time, .NET assemblies version very well.Tetrastich
"Follow your own advice and you wont need the NotImplementedException!" The point of the exception here is that you can compile while still fail if the method is called, and know why your code failed. Add the code if you get the exception - simple as that.Popcorn
Why not throw your own exception type? Why is this a .net core concept?Navvy
G
0

Here is one example: In Java, whenever you implement the interface Iterator, you have to override the obvious methods hasNext() and next(), but there is also delete(). In 99% of the usecases I have I do not need this, so I just throw a NotImplementedException. This is much better than silently doing nothing.

Gabriella answered 4/1, 2009 at 14:46 Comment(1)
Even better would be for the interface to have no delete() method. The interfaces sounds as broken as .net streams.Navvy
D
0

The NotImplementedException exists only to facilitate development. Imagine you start implementing an interface. You'd like to be able to at least build when you are done implementing one method, before moving to the next. Stubbing the NotImplemented methods with NotImplementedExceptions is a great way of living unfinished code that is super easy to spot later. Otherwise you would run the risk of quickly implementing something that you might forget to fix.

Demonetize answered 15/12, 2010 at 7:29 Comment(1)
You are free to follow what ever methodology you like, so you can "stub" all you like. Why though would Microsoft put this in the standard library? You could just as easily define your own exception to throw. If you used your own exception class, then you can remove the class definition form your code and the compiler will tell you if you've forgotten to replace one of your stubs with a real implementation - I like that much better than searching for patterns in the text... Note that you can not remove the NotImplementedException from the build, so this is not an option if you use it.Navvy
M
-1

If you don't want to use it then just ignore it. If you have a block of code whose success depends on every piece of it succeeding, but it might fail in between, then your only option is to catch the base Exception and roll back what needs to be rolled back. Forget NotImplementedException. There could be tons of exceptions thrown, like MyRandomException and GtfoException and OmgLolException. After you originally write the code I could come by and throw ANOTHER exception type from the API you're calling. One that didn't exist when you wrote your code. Handle the ones you know how to handle and rollback for any others i.e., catch(Exception). It's pretty simple, I think... I find it comes in handy too. Especially when you're trying fancy things with the language/framework that occasionally force things upon you.

One example I have is serialization. I have added properties in my .NET library that don't exist in the database (for example, convenient wrappers over existing "dumb" properties, like a FullName property that combines FirstName, MiddleName, and LastName). Then I want to serialize these data types to XML to send them over the wire (for example, from an ASP.NET application to JavaScript), but the serialization framework only serializes public properties with both get and set accessors. I don't want you to be able to set FullName because then I'd have to parse it out and there might be some unforeseen format that I wrongly parse and data integrity goes out the window. It's easier to just use the underlying properties for that, but since the language and API require me to have a set accessor, I'll throw a NotImplementedException (I wasn't aware of NotSupportedException until I read this thread, but either one works) so that if some programmer down the road does try to set FullName he'll encounter the exception during testing and realize his mistake.

Medford answered 25/6, 2010 at 14:22 Comment(2)
catch( Exception ), or the analogous catch( ... ) in C++ is one on the most evil things you can do in programming. It's called "sweeping it under the carpet" and starts your descent into a Big Ball of Mud. Putting catch( Exception ) anywhere is not simple nor handy - if you think it is, then you have a long way to go before you can write robust code. In your example, if FullName is considered immutable (ie, can not be set), why does the API have a setter for it? Something is wrong with your (or Microsoft's) design. There are a myriad of ways you could avoid adding that setter...Navvy
catch(Exception) is exactly what you want at the "top" of the application where if the exception were otherwise left unhandled the run-time would have to handle it instead, which is generally ugly and unpleasant for a user. It's essentially a crash. Examples are within Main or within Page_Load. The FullName property has a setter because the serialization API requires it, as I said in the post you commented on...Medford

© 2022 - 2024 — McMap. All rights reserved.