问题描述
这真的是真的让我,所以我希望有人可以给我一个合理的理由,为什么是这样的。
NotImplementedException。 / strong>你正在拉我的腿,对吧?
不,我不会把这个便宜的刺法说出来,说挂了,方法是实现 - 它抛出一个NotImplementedException。是的,没错,你必须实现这个方法来抛出一个NotImplementedException(与C ++中的纯虚函数调用不同 - 现在是有道理的)。虽然这很有趣,但我的脑海里有一个更严重的问题。
我只是想知道,在NotImplementedException的存在下,任何人都可以做任何事情.Net ?您是否希望使用try catch块来包装每个抽象方法调用,以防止可能无法实现的方法?如果你遇到这样的异常,你应该怎么处理它?
我没有办法测试一个方法是否实际上没有调用它。因为调用它可能会有副作用,我无法完成所有的检查,然后运行我的算法。我必须运行我的算法,捕获NotImplementedExceptions和一些如何回滚我的应用程序到一个理智的状态。
这是疯狂的。狂。疯。所以问题是:为什么存在NotImplementedException ?
作为抢先罢工,我不想让任何人回应,因为设计师需要把它放在自动生成的代码中。这是可怕的我宁愿自动生成的代码不会编译,直到你提供一个实现。例如,自动生成的实现可能是抛出NotImplementedException;没有定义NotImplementedException!
有没有人抓到并处理了NotImplementedException?你有没有在你的代码中留下NotImplementedException?如果是这样,这是代表一个定时炸弹(即你不小心把它留在那里)还是设计缺陷(该方法不应该被执行,永远不会被调用)?
我非常怀疑NotSupportedException ...不支持?什么?如果不支持,为什么是界面的一部分?微软的任何人都可以拼写不正当的遗产吗?但是,如果我不对这个滥用太多,我可能会再来一个问题。
附加信息:
,NotImplementedException是针对尚未实现的功能,但实际上应该是(而且将会)。当您正在构建类时,您可能会开始获取所有方法抛出NotImplementedException,然后用真实代码清除它们...
来自非常弱,应该被忽略:NotImplementedException:抛出此异常一种类型不会实现任何其他原因的方法。
在这个问题上更弱,仅仅表示当请求的方法或操作未被实现时抛出异常。
有一种情况我觉得很有用:TDD。
我写了我的测试,然后我创建存根,以便测试编译。那些存根只做抛出新的NotImplementedException();
。这样,默认情况下,测试将失败,无论如何。如果我使用一些虚拟返回值,它可能会产生错误的肯定。现在所有的测试编译失败,因为没有实现,我处理这些存根。
由于我从不使用 NotImplementedException
在任何其他情况下,没有 NotImplementedException
将会传递到发布代码,因为它总是会使一些测试失败。
你不需要在整个地方抓住它。良好的API记录了抛出的异常。这些是你应该寻找的。
编辑:我写了一个FxCop规则来找到它们。
这是代码:
using System;
使用Microsoft.FxCop.Sdk;
///< summary>
///一个FxCop规则来确保没有< see cref =NotImplementedException/>是
///留下的生产代码。
///< / summary>
内部类DoNotRaiseNotImplementedException:BaseIntrospectionRule
{
private TypeNode _notImplementedException;
私人会员_currentMember;
public DoNotRaiseNotImplementedException()
:base(DoNotRaiseNotImplementedException,
//以下字符串必须是程序集名称(这里是
// Bevonn.CodeAnalysis)通过一个点,然后
//元数据文件名没有xml扩展名(这里是
// DesignRules)。有关更多详细信息,请参阅最后的注释
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问题;
}
public override void VisitThrow(ThrowNode throwInstruction)
{
if(throwInstruction.Expression!= null&&
throwInstruction.Expression。 Type.IsAssignableTo(_notImplementedException))
{
var problem = new问题(
GetResolution(),
throwInstruction.SourceContext,
_currentMember.Name.Name);
Problems.Add(问题);
}
}
}
这是规则元数据:
<?xml version =1.0encoding =utf-8?>
< Rules FriendlyName =Bevonn Design Rules>
< Rule TypeName =DoNotRaiseNotImplementedExceptionCategory =Bevonn.DesignCheckId =BCA0001>
< Name>不要引发NotImplementedException< / Name>
< Description> NotImplementedException不应用于生产代码。< / Description>
< Url> http://stackoverflow.com/questions/410719/notimplementedexception-are-they-kidding-me< / Url>
< Resolution>实现方法或属性访问器。< / Resolution>
< MessageLevel Certainty =100> CriticalError< / MessageLevel>
< Email>< / Email>
< FixCategories> NonBreaking< / FixCategories>
< Owner>< / Owner>
< / Rule>
< / Rules>
要构建这个,您需要:
-
参考
Microsoft.FxCop.Sdk.dll
和Microsoft.Cci.dll
-
将元数据放入名为
DesignRules.xml
的文件中,并将其作为嵌入资源添加到您的程序集 -
命名您的程序集
Bevonn.CodeAnalysis
。如果要为元数据或汇编文件使用不同的名称,请确保相应地将第二个参数更改为基础构造函数。
然后只需将生成的程序集添加到您的FxCop规则中,并从宝贵的代码中删除这些已被禁止的异常。有一些角色的情况下,当一个被抛出的时候它不会报告一个NotImplementedException,但如果你真的写这样的Cthulhian代码,我真的认为你没有希望。对于正常使用,即抛出新的NotImplementedException();
,它的工作,这就是重要的。
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."
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>http://stackoverflow.com/questions/410719/notimplementedexception-are-they-kidding-me</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
andMicrosoft.Cci.dll
Put the metadata in a file called
DesignRules.xml
and add it as an embedded resource to your assemblyName 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.
这篇关于为什么不存在NotImplementedException?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!