System Linq checked keyword and static exceptions


Posted on January 09, 2014

I was looking at the underlying IL code for Count(IEnumerable) in System.Linq and noticed a couple of things I like..

// System.Linq.Enumerable
/// Returns the number of elements in a sequence.
///The number of elements in the input sequence.
///A sequence that contains elements to be counted.
/// The type of the elements of .
/// 
///    is null.
/// The number of elements in  is larger than .
public static int Count<TSource>(this IEnumerable <TSource> source)
{
 if (source == null)
 {
  throw Error.ArgumentNull("source");
 }
 ICollection<TSource> collection = source as ICollection <TSource>;
 if (collection != null)
 {
  return collection.Count;
 }
 ICollection collection2 = source as ICollection;
 if (collection2 != null)
 {
  return collection2.Count;
 }
 int num = 0;
 checked
 {
  using (IEnumerator <TSource> enumerator = source.GetEnumerator())
  {
   while (enumerator.MoveNext())
   {
    num++;
   }
  }
  return num;
 }
}


Firstly, the checked keyword Which apparently checks at compile time whether or not an integer operation may result in an overflow. So whilst this will compile..

// The following example causes compiler error CS0220 because 2147483647 
// is the maximum value for integers.  
//int i1 = 2147483647 + 10; 

// The following example, which includes variable ten, does not cause 
// a compiler error. 
int ten = 10;
int i2 = 2147483647 + ten;

// By default, the overflow in the previous statement also does 
// not cause a run-time exception. The following line displays  
// -2,147,483,639 as the sum of 2,147,483,647 and 10.
Console.WriteLine(i2);


This will not

/ If the previous sum is attempted in a checked environment, an  
// OverflowException error is raised. 

// Checked expression.
Console.WriteLine(checked(2147483647 + ten));

// Checked block. 
checked
{
    int i3 = 2147483647 + ten;
    Console.WriteLine(i3);
}


As described here http://msdn.microsoft.com/en-us/library/74b4xzyw.aspx and secondly how the predefined Exceptions are stored statically in an Error class ready to be thrown..

throw Error.ArgumentNull("source");


refers to this class..

internal static class Error
 {
  internal static Exception ArgumentArrayHasTooManyElements(object p0)
  {
   return new ArgumentException(Strings.ArgumentArrayHasTooManyElements(p0));
  }
  internal static Exception ArgumentNotIEnumerableGeneric(object p0)
  {
   return new ArgumentException(Strings.ArgumentNotIEnumerableGeneric(p0));
  }
  internal static Exception ArgumentNotSequence(object p0)
  {
   return new ArgumentException(Strings.ArgumentNotSequence(p0));
  }
  internal static Exception ArgumentNotValid(object p0)
  {
   return new ArgumentException(Strings.ArgumentNotValid(p0));
  }
  internal static Exception IncompatibleElementTypes()
  {
   return new ArgumentException(Strings.IncompatibleElementTypes);
  }
  internal static Exception ArgumentNotLambda(object p0)
  {
   return new ArgumentException(Strings.ArgumentNotLambda(p0));
  }
  internal static Exception MoreThanOneElement()
  {
   return new InvalidOperationException(Strings.MoreThanOneElement);
  }
  internal static Exception MoreThanOneMatch()
  {
   return new InvalidOperationException(Strings.MoreThanOneMatch);
  }
  internal static Exception NoArgumentMatchingMethodsInQueryable(object p0)
  {
   return new InvalidOperationException(Strings.NoArgumentMatchingMethodsInQueryable(p0));
  }
  internal static Exception NoElements()
  {
   return new InvalidOperationException(Strings.NoElements);
  }
  internal static Exception NoMatch()
  {
   return new InvalidOperationException(Strings.NoMatch);
  }
  internal static Exception NoMethodOnType(object p0, object p1)
  {
   return new InvalidOperationException(Strings.NoMethodOnType(p0, p1));
  }
  internal static Exception NoMethodOnTypeMatchingArguments(object p0, object p1)
  {
   return new InvalidOperationException(Strings.NoMethodOnTypeMatchingArguments(p0, p1));
  }
  internal static Exception NoNameMatchingMethodsInQueryable(object p0)
  {
   return new InvalidOperationException(Strings.NoNameMatchingMethodsInQueryable(p0));
  }
  internal static Exception ArgumentNull(string paramName)
  {
   return new ArgumentNullException(paramName);
  }
  internal static Exception ArgumentOutOfRange(string paramName)
  {
   return new ArgumentOutOfRangeException(paramName);
  }
  internal static Exception NotImplemented()
  {
   return new NotImplementedException();
  }
  internal static Exception NotSupported()
  {
   return new NotSupportedException();
  }
 }
 
 

-- Lee