I have a class that can be created with data or with a binary reader (which it uses to deserialize it's data). It does additional initialization with the data, and since I don't want to duplicate that code, I want to chain the constructors. Right now this chaining looks like this:
public Item(string id, int count = 1) { /*...*/ }
public Item(BinaryReader reader) : this(reader.ReadString(), reader.ReadInt32()) { /*...*/ }
Is order in which these read calls are made deterministic?
Clarification: I was talking about the order in which read.ReadString() and reader.ReadInt32() are called.
The exact behavior of the order of evaluation when calling methods with multiple arguments is documented in the C# specification Run-time evaluation of argument lists which states:
During the run-time processing of a function member invocation (Compile-time checking of dynamic overload resolution), the expressions or variable references of an argument list are evaluated in order, from left to right, as follows:
So in your case the order will be:
reader.ReadString()
reader.ReadInt32()
finally the other constructor will be called
Now, there are a couple of problem with this, mainly related to readability and exceptions.
The fact that you ask which call order is the correct one, the next programmer might have the same question. It would be better to refactor this into a different solution that doesn't come with a lot of questions attached.
Additionally, if you pass in a null reader you'll get a NullReferenceException instead of a ArgumentNullException, even if you should happen to validate this parameter not being null inside the constructor, simply because all this evaluation will happen before the constructor body executes. There are hacks to "fix" this but they are worse than the code you already have.
To refactor into a "better" solution (my opinion) you would create a factory method like this:
public static Item Create(BinaryReader reader)
{
if (reader == null) throw new ArgumentNullException(nameof(reader));
// optional: handle exceptions from reader.ReadString and ReadInt32
var s = reader.ReadString();
var i = reader.ReadInt32();
return new Item(s, i);
}
Related
For example, you usually don't want parameters in a constructor to be null, so it's very normal to see some thing like
if (someArg == null)
{
throw new ArgumentNullException(nameof(someArg));
}
if (otherArg == null)
{
throw new ArgumentNullException(nameof(otherArg));
}
It does clutter the code a bit.
Is there any way to check an argument of a list of arguments better than this?
Something like "check all of the arguments and throw an ArgumentNullException if any of them is null and that provides you with the arguments that were null.
By the way, regarding duplicate question claims, this is not about marking arguments with attributes or something that is built-in, but what some call it Guard Clauses to guarantee that an object receives initialized dependencies.
With newer version of C# language you can write this without additional library or additional method call:
_ = someArg ?? throw new ArgumentNullException(nameof(someArg));
_ = otherArg ?? throw new ArgumentNullException(nameof(otherArg));
Starting from .NET6 you can also write this:
ArgumentNullException.ThrowIfNull(someArg);
Starting from .NET7 you can handle empty string and null checking:
ArgumentException.ThrowIfNullOrEmpty(someStringArg);
public static class Ensure
{
/// <summary>
/// Ensures that the specified argument is not null.
/// </summary>
/// <param name="argumentName">Name of the argument.</param>
/// <param name="argument">The argument.</param>
[DebuggerStepThrough]
[ContractAnnotation("halt <= argument:null")]
public static void ArgumentNotNull(object argument, [InvokerParameterName] string argumentName)
{
if (argument == null)
{
throw new ArgumentNullException(argumentName);
}
}
}
usage:
// C# < 6
public Constructor([NotNull] object foo)
{
Ensure.ArgumentNotNull(foo, "foo");
...
}
// C# >= 6
public Constructor([NotNull] object bar)
{
Ensure.ArgumentNotNull(bar, nameof(bar));
...
}
The DebuggerStepThroughAttribute comes in quite handy so that in case of an exception while debugging (or when I attach the debugger after the exception occurred) I will not end up inside the ArgumentNotNull method but instead at the calling method where the null reference actually happened.
I am using ReSharper Contract Annotations.
The ContractAnnotationAttribute makes sure that I never misspell
the argument ("foo") and also renames it automatically if I rename
the foo symbol.
The NotNullAttribute helps ReSharper with code analysis. So if I do new Constructor(null) I will get a warning from ReSharper that this will lead to an exception.
If you do not like to annotate your code directly,
you can also do the same thing with external XML-files that you could deploy with your library and that users can optionally reference in their ReSharper.
If you have too many parameters in your constructors, you'd better revise them, but that's another story.
To decrease boilerplate validation code many guys write Guard utility classes like this:
public static class Guard
{
public static void ThrowIfNull(object argumentValue, string argumentName)
{
if (argumentValue == null)
{
throw new ArgumentNullException(argumentName);
}
}
// other validation methods
}
(You can add other validation methods that might be necessary to that Guard class).
Thus it only takes one line of code to validate a parameter:
private static void Foo(object obj)
{
Guard.ThrowIfNull(obj, "obj");
}
Null references are one sort of troubles you have to guard against. But, they are not the only one. The problem is wider than that, and it boils down to this: Method accepts instances of a certain type, but it cannot handle all instances.
In other words, domain of the method is larger than the set of values it handles. Guard clauses are then used to assert that actual parameter does not fall into that "gray zone" of the method's domain which cannot be handled.
Now, we have null references, as a value which is typically outside the acceptable set of values. On the other hand, it often happens that some non-null elements of the set are also unacceptable (e.g. empty string).
In that case, it may turn out that the method signature is too broad, which then indicates a design problem. That may lead to a redesign, e.g. defining a subtype, typically a derived interface, which restricts domain of the method and makes some of the guard clauses disappear. You can find an example in this article: Why do We Need Guard Clauses?
With newer version of C# (C# 10, .NET6 will be released in a few days) you can even do:
ArgumentNullException.ThrowIfNull(someArg);
Doc: https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception.throwifnull?view=net-6.0
Ardalis has an excellent GuardClauses library.
It's nice to use Guard.Against.Null(message, nameof(message));
In C# 8.0 and later, new helps are available. C# 8.0 introduces non-nullable reference types (a feature somewhat confusingly called "nullable reference types" in the docs). Prior to C# 8.0, all reference types could be set to null. But now with C# 8.0 and the 'nullable' project setting, we can say that reference types are by default non-nullable, and then make our variables and parameters nullable on a case-by-case basis.
So whereas at the moment, we recognize code like this:
public void MyFunction(int thisCannotBeNull, int? thisCouldBeNull)
{
// no need for checking my thisCannotBeNull parameter for null here
}
If you set <Nullable>enable</Nullable> for your C# v8.0+ project, you can do things like this too:
public void MyFunction(MyClass thisCannotBeNull, MyClass? thisCouldBeNull)
{
// static code analysis at compile time checks to see if thisCannotBeNull could be null
}
The null-checking is done at compile-time, using static code analysis. So if you've coded it in a way that means a null could turn up there, you'll get a compiler warning (which you can upgrade to an error if you want). So lots (but not all) of the situations where you need a run-time check for null parameters can be handled as a compile-time check based on your code.
The !! operator (not actually part of C#, but interesting story)
Microsoft attempted to introduce a new language feature that was known as parameter null checking or also as the bang bang operator in C# 10 and later again in C# 11, but decided to not release it.
It would have been the shortest way to do this (by far): only 2 exclamation marks !! right after the argument(s) you want to check for null.
Before:
public void test(string someArg){
if (someArg == null)
{
throw new ArgumentNullException(nameof(someArg));
}
// other code
}
With that new operator:
public void test(string someArg!!){
// other code
}
Calling test(null) would have lead to an ArgumentNullException telling you that someArg is null.
Microsoft mentioned it in early 2021, but it did not become part of C# 10: A video on the 'Microsoft Developer' YouTube channel explaining the new feature.
The feature was implemented in February 2022 for C#11, see on GitHub.
It was removed later see on Microsoft dev blog because of lots of criticism with the argument, that the bang bang operator is very shouty.
The developers of the C# language think, that there is a majority for such a feature, but that it's not as large as usual and that it's possible, that this features comes with a later C# version.
You might try my Heleonix.Guard library, which provides guard functionality.
You can write guard clauses like below:
// C# 7.2+: Non-Trailing named arguments
Throw.ArgumentNullException(when: param.IsNull(), nameof(param));
// OR
// Prior to C# 7.2: You can use a helper method 'When'
Throw.ArgumentNullException(When(param.IsNull()), nameof(param));
// OR
Throw.ArgumentNullException(param == null, nameof(param));
// OR
Throw.ArgumentNullException(When (param == null), nameof(param));
It provides throwing of many existing exceptions, and you can write custom extension methods for custom exceptions. Also, the library refers to the 'Heleonix.Extensions' library with predicative extensions like IsNull, IsNullOrEmptyOrWhitespace, IsLessThan and many more to check your arguments or variables against desired values. Unlike some other guard libraries with fluent interfaces, these extensions do not generate intermediate objects, and since implementation is really straightforward, they are performant.
If you want to save typing the argument name twice, like
Guard.AgainstNull(arg, nameof(arg));
check out YAGuard, where you can write
Guard.AgainstNull(arg);
No need to specify the name of the argument in the guard clause, but in the argument thrown, the name is correctly resolved.
It also supports guard-and-set in the form
MyProperty = Assign.IfNotNull(arg);
Nuget: YAGuard
Disclaimer: I'm the author of YAGuard.
The simplest approach I've found is inspired by Dapper's use of anonymous types.
I've written a Guard class that uses anonymous types to get name of properties.
The guard itself is the following
public class Guard
{
public static void ThrowIfNull(object param)
{
var props = param.GetType().GetProperties();
foreach (var prop in props)
{
var name = prop.Name;
var val = prop.GetValue(param, null);
_ = val ?? throw new ArgumentNullException(name);
}
}
}
You then use it like so
...
public void Method(string someValue, string otherValue)
{
Guard.ThrowIfNull(new { someValue, otherValue });
}
...
When the ArgumentNullException is thrown, reflection is used to determine the name of the property which will then be displayed in your exception
There is a nuget package called SwissKnife. Install SwissKnife from nuget gallery. It provides you with many options starting with null checking for arguments
Argument.IsNotNullOrEmpty(args,"args") under SwissKnife.Diagnostics.Contracts namespace alongwith with option idoim and many more. You can set Option<Class_Name> _someVar and then check if _someVar.IsSome or _someVar.IsNone. This helps against nullable classes as well. Hope this helps.
I want to know what exception(is there any in .NET) should I throw when called method returns unexpected result.
For example, imagine situation where I have factory:
public abstract class Factory
{
public A Create()
{
var a = new A();
var b = CreateDependencyOfA();
a.Something = b.Property;
}
protected abstract B CreateDependencyOfA();
}
I document that class and create assumption that CreateDependencyOfA does not return null(or anything else, i.e. for integer assuming that value is between 1 and 5).
What should I do when implementation breaks this contract (returning in this case null). Is there in .NET any exception type designed for this purpose? I know there are some ArgumentExceptions but they, from what I know, for input parameters . Is there equivalent for output parameters?
I am asking this because I believe there is some kind of symmetry between input and output parameters but I do not know any exceptions for output.
If a method returns a value that it should never return, it means that there is an internal logic error in your program. Errors of this kind (i.e. situations that must never happen if the code is designed to specification) are best handled by assertions:
var dependency = Factory.CreateDependencyOfA();
Debug.Assert(dependency != null, "Factory returned null dependency.");
Note: use of assertions assumes that you are checking the output of your own method. In other words, you own the Factory and all its implementations, that you wrote all the CreateDependencyOfA methods, and that you know that these methods must not return null.
If an implementation of the Factory is a plug-in written by somebody else, you should not use an assertion. Instead, use InvalidOperationException to indicate that the current state (namely, the Factory implementation supplied to you) is invalid.
You may want to check out Code Contracts: http://msdn.microsoft.com/en-us/library/dd264808(v=vs.110).aspx
For example, your CreateDependencyOfA method might include a contract such as:
Contract.Ensures(Contract.Result<B>() != null);
I've always thought that it's impossible for this to be null inside instance method body. Following simple program demonstrates that it is possible. Is this some documented behaviour?
class Foo
{
public void Bar()
{
Debug.Assert(this == null);
}
}
public static void Test()
{
var action = (Action)Delegate.CreateDelegate(typeof (Action), null, typeof(Foo).GetMethod("Bar"));
action();
}
UPDATE
I agree with the answers saying that it's how this method is documented. However, I don't really understand this behaviour. Especially because it's not how C# is designed.
We had gotten a report from somebody (likely one of the .NET groups
using C# (thought it wasn't yet named C# at that time)) who had
written code that called a method on a null pointer, but they didn’t
get an exception because the method didn’t access any fields (ie
“this” was null, but nothing in the method used it). That method then
called another method which did use the this point and threw an
exception, and a bit of head-scratching ensued. After they figured it
out, they sent us a note about it.
We thought that being able to call a method on a null instance was a
bit weird. Peter Golde did some testing to see what the perf impact
was of always using callvirt, and it was small enough that we decided
to make the change.
http://blogs.msdn.com/b/ericgu/archive/2008/07/02/why-does-c-always-use-callvirt.aspx
Because you're passing null into the firstArgument of Delegate.CreateDelegate
So you're calling an instance method on a null object.
http://msdn.microsoft.com/en-us/library/74x8f551.aspx
If firstArgument is a null reference and method is an instance method,
the result depends on the signatures of the delegate type type and of
method:
If the signature of type explicitly includes the hidden first
parameter of method, the delegate is said to represent an open
instance method. When the delegate is invoked, the first argument in
the argument list is passed to the hidden instance parameter of
method.
If the signatures of method and type match (that is, all parameter
types are compatible), then the delegate is said to be closed over a
null reference. Invoking the delegate is like calling an instance
method on a null instance, which is not a particularly useful thing to
do.
Sure you can call into a method if you are using the call IL instruction or the delegate approach. You will set this booby trap only off if you try to access member fields which will give you the NullReferenceException you did seek for.
try
int x;
public void Bar()
{
x = 1; // NullRefException
Debug.Assert(this == null);
}
The BCL does even contain explicit this == null checks to aid debugging for languages which do not use callvirt (like C#) all the time. See this question for further infos.
The String class for example has such checks. There is nothing mysterious about them except that you will not see the need for them in languages like C#.
// Determines whether two strings match.
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
public override bool Equals(Object obj)
{
//this is necessary to guard against reverse-pinvokes and
//other callers who do not use the callvirt instruction
if (this == null)
throw new NullReferenceException();
String str = obj as String;
if (str == null)
return false;
if (Object.ReferenceEquals(this, obj))
return true;
return EqualsHelper(this, str);
}
Try the documentation for Delegate.CreateDelegate() at msdn.
You're "manually" calling everything, and thus instead of passing an instance in for the this pointer, you're passing null. So it can happen, but you have to try really really hard.
this is a reference, so there is no problem with its being null from the perspective of the type system.
You may ask why NullReferenceException was not thrown. The full list of circumstances when CLR throws that exception is documented. Your case is not listed. Yes, it is a callvirt, but to Delegate.Invoke (see here) rather than to Bar, and so the this reference is actually your non-null delegate!
The behavior you see has an interesting implementational consequence for CLR. A delegate has a Target property (corresponds to your this reference) that is quite frequently null, namely when the delegate is static (imagine Bar be static). Now there is, naturally, a private backing field for the property, called _target. Does _target contain a null for a static delegate? No it doesn't. It contains a reference to the delegate itself. Why not null? Because a null is a legitimate target of a delegate as your example shows and CLR does not have two flavors of a null pointer to distinguish the static delegate somehow.
This bit of trivium demonstrates that with delegates, null targets of instance methods are no afterthought. You may still be asking the ultimate question: but why they had to be supported?
The early CLR had an ambitious plan of becoming, among others, the platform of choice even for sworn C++ developers, a goal that was approached first with Managed C++ and then with C++/CLI. Some too challenging language features were omitten, but there was nothing really challenging about supporting instance methods executing without an instance, which is perfectly normal in C++. Including delegate support.
The ultimate answer therefore is: because C# and CLR are two different worlds.
More good reading and even better reading to show the design allowing null instances shows its traces even in very natural C# syntactic contexts.
this is a readonly reference in C# classes. Accordingly and as expected this can be used like any other references (in read only mode) ...
this == null // readonly - possible
this = new this() // write - not possible
Personally, I'm a fan of the fluent interface syntax of the IEnumerable/List extension methods in C#, as a client. That is, I prefer syntax like this:
public void AddTheseGuysToSomeLocal(IEnumerable<int> values)
{
values.ToList().ForEach(v => _someLocal += v);
}
as opposed to a control structure like a foreach loop. I find that easier to process mentally, at a glance. Problem with this is that my code here is going to generate null reference exceptions if clients pass me a null argument.
Let's assume that I don't want to consider a null enumeration to be exceptional -- I want that to result in leaving some local as-is -- I would add a null guard. But, that's a little syntactically noisy for my taste, and that noise adds up in cases where you're chaining these together in a fluent interface and the interim results can be null as well.
So, I created a class called SafeEnumerableExtensions that offers a no-throw guarantee by treating nulls as empty enumerables (lists). Example methods include:
//null.ToList() returns empty list
public static List<T> SafeToList<T>(this IEnumerable<T> source)
{
return (source ?? new List<T>()).ToList();
}
//x.SafeForEach(y) is a no-op for null x or null y
//This is a shortcut that should probably go in a class called SafeListExtensions later
public static void SafeForEach<T>(this List<T> source, Action<T> action)
{
var myAction = action ?? new Action<T>(t => { });
var mySource = source ?? new List<T>();
mySource.ForEach(myAction);
}
public static void SafeForEach<T>(this IEnumerable<T> source, Action<T> action)
{
SafeToList(source).SafeForEach(action);
}
Now, my original method is prettier than if there were a null guard, but just as safe, since null result in a no-op:
public void AddTheseGuysToSomeLocal(IEnumerable<int> values)
{
values.ForEach(v => _someLocal += v);
}
So, my question is twofold. (1) I'm assuming that I'm not so original as to be the first person ever to have thought of this -- does anyone know if there is an existing library that does this or something similar? And (2) has anyone used said library or implemented a scheme like this and experienced unpleasant consequences or else can anyone foresee unpleasant consequences for doing something like this? Is this even a good idea?
(I did find this question when checking for duplicates, but I don't want to explicitly do this check in clients - I want the extension class to do this implicitly and not bother clients with that extra method call)
And (2) has anyone used said library or implemented a scheme like this
and experienced unpleasant consequences or else can anyone foresee
unpleasant consequences for doing something like this? Is this even a
good idea?
Personally I would consider this a bad idea. In most cases passing a null enumeration or null Func is probably not intended.
You are "fixing" the problem which might lead to seemingly unrelated problems later down the road. Instead I would rather throw an exception in this case so that you find this problem in your code early on ("Fail fast").
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.)
I think #Jon Skeet is absolutely spot on, however I'd like to add the following thoughts:-
Providing a meaningful error message is useful for debugging, logging and exception reporting. An exception thrown by the BCL is less likely to describe the specific circumstances of the exception WRT your codebase. Perhaps this is less of an issue with null checks which (most of the time) necessarily can't give you much domain-specific information - 'I was passed a null unexpectedly, no idea why' is pretty much the best you can do most of the time, however sometimes you can provide more information and obviously this is more likely to be relevant when dealing with other exception types.
The null check clearly demonstrates to other developers and you, a form of documentation, if/when you come back to the code a year later, that it's possible someone might pass a null, and it would be problematic if they did so.
Expanding on Jon's excellent point - you might do something before the null gets picked up - I think it is vitally important to engage in defensive programming. Checking for an exception before running other code is a form of defensive programming as you are taking into account things might not work the way you expected (or changes might be made in the future that you didn't expect) and ensuring that no matter what happens (assuming your null check isn't removed) such problems cannot arise.
It's a form of runtime assert that your parameter is not null. You can proceed on the assumption that it isn't.
The above assumption can result in slimmer code, you write the rest of your code knowing the parameter is not null, cutting down on extraneous subsequent null checks.
In my opinion you should check for the null value. Two things that comes to mind.
It makes explicit the possible errors that can happen during runtime.
It also gives you a chance to throw a better exception instead of a generic ArgumentNullException. Thus, making the reason for the exception more explicit.
The exception that you will get thrown will be an Object reference not set to an instance of an object.
Not the most useful of exceptions when tracking down the problem.
The way you have it there will give you much more useful information by specifically stating that it's your subjects reference that is null.
I think it is a good practice to do precondition checks at the top of the function. Maybe it's just my code that is full of bugs, but this practice catched a lot of errors for me.
Also, it's much easier to figure out the source of the problem if you got an ArgumentNullException with the name of the parameter, thrown from the most relevant stack frame. Also, the code in the body of your function can change over time so I wouldn't depend on it catching precondition problems in the future.
It always depends on the context (in my opinion).
For instance, when writing a library (for others to use), it certainly makes sense to fully check each and every parameter and throw the appropriate exceptions.
When writing methods that are used inside a project, I usually skip those checks, attempting to reduce the size of the codebase. But even in this case, there might be a level (between application layers) where you still place such checks. It depends on the context, on the size of the project, on the size of the team working on it...
It certainly doesn't make sense doing it for small projects built by one person :)
It depends on the concrete method. In this case - I think, the exception is not necesary and the better usage will be, if teh extension method can deal with null.
public static bool HasFive<T>(this IEnumerable<T> subjects) {
if ( object.ReferenceEquals( subjects, null ) ) { return false; }
return subjects.Count() == 5;
}
If you call "items.HasFive()" and the "items" is null, then is true that items has not five items.
But if you have extension method:
public static T GetFift<T>(this IEnumerable<T> subjects) {
...
}
The exception for "subjects == null" should be called, because there is no valid way, how to deal with it.
If you look at the source to the Enumerable class (System.Core.dll) where a lot of the default extension methods are defined for IEnumerables classes, you can see that they all check for null references with arguments.
public static IEnumerable<TSource> Skip<TSource>(this IEnumerable<TSource> source, int count)
{
if (source == null)
{
throw Error.ArgumentNull("source");
}
return SkipIterator<TSource>(source, count);
}
It's a bit of an obvious point, but I tend to follow what I find in the base framework library source as you know that is more than likely to be best practices.
Yes, for two reasons:
Firstly, the other extension methods on IEnumerable do and consumers of your code can expect yours to do so as well, but secondly and more importantly, if you have a long chain of operators in your query then knowing which one threw the exception is useful information.
In my opinion one should check for known conditions that will raise errors later on (at least for public methods). That way it's easier to detect the root of the problem.
I would raise a more informational exception like:
if (subjects == null)
{
throw new ArgumentNullException("subjects ", "subjects is null.");
}