Why does NotImplementedException exist?

2019-01-04 17:11发布

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."

27条回答
我欲成王,谁敢阻挡
2楼-- · 2019-01-04 17:56

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?

查看更多
霸刀☆藐视天下
3楼-- · 2019-01-04 17:57

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).

查看更多
在下西门庆
4楼-- · 2019-01-04 17:57

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.

查看更多
成全新的幸福
5楼-- · 2019-01-04 17:58

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

查看更多
放荡不羁爱自由
6楼-- · 2019-01-04 17:59

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

查看更多
叛逆
7楼-- · 2019-01-04 17:59

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.

查看更多
登录 后发表回答