本文介绍了C#:我应该懒得在这种情况下检查空?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

可以说我有这种延伸方式:

 公共静态布尔HasFive< T>(这个IEnumerable的< T>学科) 
{
如果(科目== NULL)
抛出新的ArgumentNullException(科目);

返回subjects.Count()== 5;
}



你认为这空检查和异常抛出真的是必要的吗?我的意思是,当我使用计数方法, ArgumentNullException 将反正扔了吧?



我也许可以想到的一个原因,我为什么要,但只是想听听其他人对此的看法。是的,我之所以问的是部分懒惰(要尽可能少写),而且还因为我有点想了一堆空的检查和异常抛出一种杂波了这往往最终成为该方法的两倍,只要他们真正需要的是。有人应该知道不如发送空到一个方法:P



不管怎么说,你们觉得什么






注意: COUNT()是一个扩展方法的将会的抛出 ArgumentNullException ,而不是的NullReferenceException 。请参见。自己尝试一下,如果你不相信我=)






注2 这里给出的答案后,我一直在说服开始检查多为空值。我还懒的,所以我已经开始使用实施类的。可以建议采取看看吧。相反,我的例子,我可以做到这一点,而不是:

 公共静态布尔HasFive< T>(这个IEnumerable的< T>科目)
{
Enforce.Argument(()=>学科);
返回subjects.Count()== 5;
}


解决方案

是的,它会抛出一个 ArgumentNullException 。我能想到的两个原因把额外的检查中:




  • 如果您以后回来之前调用改做事情的方法 subjects.Count()忘记把支票在这一点上,你可以在异常抛出之前,这是不是很好用的副作用结束。

  • 目前,堆栈跟踪将显示 subjects.Count()上方,并可能与使用源参数名称。这可能会产生混淆 HasFive 的调用者谁可以看到主题参数名称。



编辑:只是为了救我不得不写又一次在别处:



要调用 subjects.Count()将抛出一个 ArgumentNullException 的一个的NullReferenceException COUNT()是另一种扩展方法在这里,假设在 System.Linq.Enumerable 的实施正在被使用,这是记录(正确)抛出 ArgumentNullException 。 。试试吧,如果你不相信我的话。



编辑:使这个容易...



如果您做了很多检查,这样你可能要更简单地这样做的。我喜欢下面的扩展方法:

 内部静态无效ThrowIfNull< T>(这件T的说法,字符串名称)
其中T:类
{
如果(参数== NULL)
{
抛出新的ArgumentNullException(名);
}
}

在问题中所说的方法就可以变成:

 公共静态布尔HasFive< T>(这个IEnumerable的< T>学科)
{
subjects.ThrowIfNull (科目);
返回subjects.Count()== 5;
}



另一种方法是写它检查值一个版本的和回到住处的是这样的:

 内部静态牛逼NullGuard< T>(这件T的说法,字符串名称)
,其中T:类
{
如果(参数== NULL)
{
抛出新的ArgumentNullException(名);
}
返回参数;
}

您就可以流利地调用它:

 公共静态布尔HasFive< T>(这个IEnumerable的< T>科目)。
{
返回subjects.NullGuard(科)计数()== 5;
}

这也是在构造函数中复制参数等有帮助的:

 公众人物(字符串名称,诠释岁)
{
this.name = name.NullGuard(名称);
this.age =年龄;
}



(您可能希望在不为地方参数名的重载它并不重要。)


Lets say I have this extention method:

public static bool HasFive<T>(this IEnumerable<T> subjects)
{
    if(subjects == null)
        throw new ArgumentNullException("subjects");

    return subjects.Count() == 5;
}

Do you think this null check and exception throwing is really necessary? I mean, when I use the Count method, an ArgumentNullException will be thrown anyways, right?

I can maybe think of one reason why I should, but would just like to hear others view on this. And yes, my reason for asking is partly laziness (want to write as little as possible), but also because I kind of think a bunch of null checking and exception throwing kind of clutters up the methods which often end up being twice as long as they really needed to be. Someone should know better than to send null into a method :p

Anyways, what do you guys think?


Note: Count() is an extension method and will throw an ArgumentNullException, not a NullReferenceException. See Enumerable.Count<TSource> Method (IEnumerable<TSource>). Try it yourself if you don't believe me =)


Note2: After the answers given here I have been persuaded to start checking more for null values. I am still lazy though, so I have started to use the Enforce class in Lokad Shared Libraries. Can recommend taking a look at it. Instead of my example I can do this instead:

public static bool HasFive<T>(this IEnumerable<T> subjects)
{
    Enforce.Argument(() => subjects);
    return subjects.Count() == 5;
}
解决方案

Yes, it will throw an ArgumentNullException. I can think of two reasons for putting the extra checking in:

  • If you later go back and change the method to do something before calling subjects.Count() and forget to put the check in at that point, you could end up with a side effect before the exception is thrown, which isn't nice.
  • Currently, the stack trace will show subjects.Count() at the top, and probably with a message with the source parameter name. This could be confusing to the caller of HasFive who can see a subjects parameter name.

EDIT: Just to save me having to write it yet again elsewhere:

The call to subjects.Count() will throw an ArgumentNullException, not a NullReferenceException. Count() is another extension method here, and assuming the implementation in System.Linq.Enumerable is being used, that's documented (correctly) to throw an ArgumentNullException. Try it if you don't believe me.

EDIT: Making this easier...

If you do a lot of checks like this you may want to make it simpler to do so. I like the following extension method:

internal static void ThrowIfNull<T>(this T argument, string name)
    where T : class
{
    if (argument == null)
    {
        throw new ArgumentNullException(name);
    }
}

The example method in the question can then become:

public static bool HasFive<T>(this IEnumerable<T> subjects)
{
    subjects.ThrowIfNull("subjects");
    return subjects.Count() == 5;
}

Another alternative would be to write a version which checked the value and returned it like this:

internal static T NullGuard<T>(this T argument, string name)
    where T : class
{
    if (argument == null)
    {
        throw new ArgumentNullException(name);
    }
    return argument;
}

You can then call it fluently:

public static bool HasFive<T>(this IEnumerable<T> subjects)
{
    return subjects.NullGuard("subjects").Count() == 5;
}

This is also helpful for copying parameters in constructors etc:

public Person(string name, int age)
{
    this.name = name.NullGuard("name");
    this.age = age;
}

(You might want an overload without the argument name for places where it's not important.)

这篇关于C#:我应该懒得在这种情况下检查空?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

05-26 16:36
查看更多