在哪里检查对象是否为空?
在哪里检查传递给方法的对象是否为 null?
在调用方法之前是否需要测试对象? 或者在使用参数的方法中?
public class Program
{
public static void Main(string[] args)
{
// Check if person is null here? or within PrintAge?
PrintAge(new Person { Age = 1 });
}
private static void PrintAge(Person person)
{
// check if person is null here?
Console.WriteLine("Age = {0}", person.Age);
}
}
public class Person
{
public int Age { get; set; }
}
在两个类中进行“空”检查似乎是太多冗余代码。
[编辑]:在调用者或被调用者中检查 null 的缺点/优点是什么?
[EDIT2]:我刚刚遇到了防御性编程,看起来像它提倡在被调用者中检查 null。 我想知道这是否是一种被广泛接受的做法。
Where do you check if an object that you are passing to a method is null or not?
Should an object need to be tested before calling a method? or within the method that is using the argument?
public class Program
{
public static void Main(string[] args)
{
// Check if person is null here? or within PrintAge?
PrintAge(new Person { Age = 1 });
}
private static void PrintAge(Person person)
{
// check if person is null here?
Console.WriteLine("Age = {0}", person.Age);
}
}
public class Person
{
public int Age { get; set; }
}
Having a "null" check in both classes seem to be too much redundant code.
[EDIT]: What would be an dis/advantage of checking for null within a caller or a callee?
[EDIT2]: I just ran into Defensive Programming and it seems like it advocates checking null within a callee. I wonder if this is a widely accepted practice.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(13)
如果你设计一个库,就会有暴露给外部世界的方法。 您应该检查此方法中传入的数据。 在您不公开的方法中不需要进行检查,因为只有您的代码调用它们,并且其逻辑应该处理您在所调用的公开方法中接受的所有情况。
如果您已经接受了输入方法中提供的数据,则应该执行请求的操作并返回预期的结果,即处理所有剩余的情况。
更新
澄清图书馆内部的情况。 可能存在空检查,但这只是因为逻辑,而不是因为参数验证。 库内空检查的位置有两种可能性。 第一个如果被调用的方法知道如何处理空值。
第二种情况是调用无法处理空值的方法。
整个想法是拒绝您无法立即处理的案件并妥善处理所有剩余案件。 如果输入无效,则会抛出异常。 这迫使库调用者仅提供有效值,并且不允许调用者以无意义的返回值继续执行(除了调用者浅化异常并继续)。
If you design a library, there will be methods exposed to the outer world. You should check the incoming data in this methods. No checks are required in methods that you do not expose, because only your code calls them and its logic should handle all cases you accepted in the exposed method called.
If you have accepted the supplied data in the entry method, you should perform the requested action and return the expected result, that is handle all remaining cases.
UPDATE
To clarify the situation inside the library. There might be null checks, but only because of the logic, not because of parameter validation. There are two possibilities for the location of null checks inside the library. The first one if the called method knows how to handle null values.
And the second situation if you call a method that cannot handle null values.
The whole idea is to reject cases you cannot handle immediately and handle all remaining cases properly. If the input is not valid you throw an exception. This forces the library caller to supply only valid values and does not allow the caller to continue execution with meaningless return values (besides the caller shallows the exception an continues).
您在
Main
中没有任何需要检查的内容 - 您使用的new
运算符永远不会返回 null(Nullable
除外) 。检查
PrintAge
是完全合理的,特别是如果它被公开的话。 (对于私有 API,进行参数检查不太重要,但它仍然非常有用。)在 C# 3.0 中,我通常 为此使用扩展方法。
You've got nothing to check in
Main
- you're using thenew
operator which never returns null (except forNullable<T>
).It would be entirely reasonable to check in
PrintAge
, particularly if it were made public. (For private APIs it's less important to do argument checking, but it can still be very useful.)These days in C# 3.0 I usually use an extension method for this.
您可以设计一种仅使用有效对象的方法。
这意味着您希望收到有效对象(在您的情况下不为空)。
这意味着您不知道如何做出反应以及如何处理无效对象:
不是解决方案;
方法,它们可以在传递给您之前检查值。
因此,如果您的方法不确切知道如何处理无效对象,并且该方法在无效情况下不会遵循额外的逻辑,您应该将其放在
PrintAge
开始,这将强制您通过调用堆栈进行检查。层次结构中越低的功能,它应该执行的检查越少。 以下是在执行该工作的函数中进行检查的缺点。
必须尽可能清楚
如果没有大量的 if
You can design a method to work with valid objects only.
That means you are expect to receive valid objects ( not null in your case ).
That means you don't know how to react and what to do with invalid objects:
is not a solution;
methods where they can check the value already before passing to you.
So if your method don't know exactly how to handle invalid object and the method won't follow additional logic in the invalid case you should put
at the
PrintAge
begin and this will force you to make checks upper by call stack.The lower function in hierarchy is the less checks it should do. The following is disadvantages of doing checks in the functions that do the work.
has to be as clear as possible
without mass of ifs
我想说,在 PrintAge 中检查它似乎更有意义,因为这是履行例程的合同。 当然,您可以用 Debug.Assert() 代码替换空检查,以在测试时进行检查,但不能在发布时进行检查。
I would say that checking it n PrintAge seemed to make more sense as that is fulfiling the contract for the routine. You could, of course, replace the null checks with Debug.Assert() code to check at test time, but not at release time.
你的意思是检查这两种方法? 我肯定会检查 PrintAge 以及它在 Main 中是否也有意义。 我认为一般来说没有明确的答案。 这取决于 :-)
You mean checking in both methods? I'd check in PrintAge for sure and if it makes sense within Main as well. I don't think there is a definite answer in general. It depends :-)
我通常让空检查由我的期望控制; 如果我期望某些内容为空或不确定,我会添加一个检查。 否则我不会。 空指针异常是最容易跟踪的问题之一,因此过多的检查会使代码膨胀。 在具体的示例中,我不会检查任何内容,因为它很直观,它不为空。
I normally let my null checks be controlled by my expectations; if I expect something to be null or am unsure of it, I add a check. Otherwise I don't. Nulllpointer exceptions are among the easiest problems to track, so excessive sprinkling of checks bloats code. In the specific example I'd check nothing, because it's intutitive it's not null.
如果实例为空,您想做什么?
我认为这取决于你提供的API & 定义契约(.net 框架类的方式)。 话虽如此,如果该方法定义了传递给它的空引用情况下的预期结果,则不需要检查空值(在 main 中)。
What would you want to do, if instance is null?
I think it depends on the API you provide & define contract (the way .net framework classes do). Having said that, you need not do a check for null (in main), if the method defines what is expected outcome in case of null reference passed to it.
据我了解你的问题比你的例子所说明的更普遍。 我的偏好如下:
Brad Abrams 在此提供了更多信息:http://blogs。 msdn.com/brada/archive/2004/07/11/180315.aspx
As I understand your question it is more general than illustrated by your example. My preferences are as follows:
Brad Abrams has some more input here: http://blogs.msdn.com/brada/archive/2004/07/11/180315.aspx
只有一种情况,构造函数可以在
Nullable
] 上返回 null [new()
] - 因此调用代码不需要检查。被调用者可能应该检查; 如果为 null,则抛出
ArgumentNullException
。 在 .NET 4.0 中,代码契约将更好地满足这一需求。 但还没有;-pThere is only one occasion that a constructor can return null [
new()
on aNullable<T>
] - so the calling code doesn't need to check.The callee probably should check; throwing an
ArgumentNullException
if it was null. In .NET 4.0 this will be better served by code contracts. But not yet ;-p冗余代码不是最优雅的,但它是安全的。
这取决于您的目标用户是谁,如果是您,那么您可以控制所有内容的使用方式,并且仅当您不确定变量的状态时才需要进行检查。
如果你做这个供其他人使用,那么空检查可能是一个好主意。 即使您只是抛出 NullPointerException,最好还是快速失败。
Redundant code isn't the most elegant but its safe.
This depends on who your intended user is, if its you then your in control of how everything is used and the checks are only necessary if your unsure of what the state of your variables will be.
If your making this for someone else to use then null checks are probably a good idea. Even if you just throw a NullPointerException its better to fast fail.
一定要检查
PrintAge
,这是一个正确的检查位置。 它可能是多余的,但不会伤害任何人,除非你每秒执行 1000 次。 (根据检查抛出异常或修复它,如果可以的话)其他检查取决于您的实际流程,在本例中您没有流程,所以我无法对此发表评论。 但通常认为你的参数被污染了。
Definitely check in
PrintAge
, it's a right place to check. It can be redundant but won't hurt anyone unless you execute it 1000 times per second. (Depending on the check throw an exception or fix it if you can)Other check is depend on your actual flow, in this example you don't have a flow so I can't comment on that bit. But generally consider your parameters as tainted.
PrintAge 应该是 Person 上的一个方法,而不是一个以 Person 作为参数的静态方法。 无需检查。
检查空值会使代码变得不必要的复杂。 构建代码以限制(或消除)可能值为 null 的情况,并且您需要编写的检查会少得多。
PrintAge should be a method on Person, not a static taking a Person as parameter. No check needed.
Checking for null values makes the code unnecessarily complex. Structure your code so as to limit (or eliminate) the occasions where null is a possible value, and you'll have much fewer checks to write.
我更喜欢在方法内部进行空检查,原因有两个。
我认为函数应该是“完整的”,即处理空值/“边缘情况”并且不依赖调用者。 这有两个原因,
在方法内进行 null 检查会减少代码内的 null 检查总数,这通常意味着代码更具可读性
I prefer null checks inside methods for two reasons.
I think functions should be 'complete', ie handle null values/'edge cases' and not rely on callers. This is for two reasons,
having null checks inside the method reduces overall number of null checks inside the code, which usually means more readable code