1. What are the First, Last, FirstOrDefault, LastOrDefault operators?
2. What are the signatures of the First, Last, FirstOrDefault, LastOrDefault operators?
3. What are the Single, SingleOrDefault operators?
4. What are the signatures of the Single, SingleOrDefault operators?
5. What are the ElementAt, ElementAtOrDefault operators?
6. What are the signatures of the ElementAt, ElementAtOrDefault operators?
7. What is the DefaultIfEmpty operator?
8. What is the signature of the DefaultIfEmpty operator?
The First, (Last), FirstOrDefault, (LastOrDefault) operator extracts the first(last) element in the source sequence. If there are no matching that verify predicate or the sequence is empty the operator First(Last) generates InvalidOperationException.
public static TSource First<TSource>(
this IEnumerable<TSource> source);
public static TSource First<TSource>(
this IEnumerable<TSource> source,
Func<TSource, bool> predicate);
public static TSource FirstOrDefault<TSource>(
this IEnumerable<TSource> source);
public static TSource FirstOrDefault<TSource>(
this IEnumerable<TSource> source,
Func<TSource, bool> predicate);
public static TSource Last<TSource>(
this IEnumerable<TSource> source);
public static TSource Last<TSource>(
this IEnumerable<TSource> source,
Func<TSource, bool> predicate);
public static TSource LastOrDefault<TSource>(
this IEnumerable<TSource> source);
public static TSource LastOrDefault<TSource>(
this IEnumerable<TSource> source,
Func<TSource, bool> predicate);
Example 1:
//InvalidOperationException: {"Sequence contains no matching element"}
var firstWithException = Data.Customers.First(c => (String.Compare(c.City, "Moscow") == 0));
Customer firstWithoutException = Data.Customers.FirstOrDefault(c => (String.Compare(c.City, "Moscow") == 0));
Trace.WriteLine("Customer: " + firstWithoutException);
Output:
Customer:
Example 2:
var lastWithException = Data.Customers.Last(c => (String.Compare(c.City, "Dallas") == 0));
Trace.WriteLine("Customer: " + lastWithException);
Output:
Customer: James – Dallas – USA
The Single, (SingleOrDefault) operator extracts the single and unique element in the source sequence. If there are no matching that verify predicate or the sequence is empty the operator Single generates the InvalidOperationException exception. In case of there more than one matching elements both operators generates the InvalidOperationException exception.
public static TSource Single<TSource>( this IEnumerable<TSource> source );
public static TSource Single<TSource>( this IEnumerable<TSource> source,
Func<TSource, bool> predicate);
public static TSource SingleOrDefault<TSource>(this IEnumerable<TSource> source);
public static TSource SingleOrDefault<TSource>( this IEnumerable<TSource> source,
Func<TSource, bool> predicate);
Example 3:
// InvalidOperationException: Sequence contains more than one matching element
var exprSingleOrDefaultWithMoreThanOne = (from c in Data.Customers
from o in c.Orders
select o).SingleOrDefault(o => o.IdProduct == 1);
Output:
// InvalidOperationException: Sequence contains more than one matching element
Example 4:
var exprSingleOrDefaultWithoutMatchingElements = (from c in Data.Customers
from o in c.Orders
select o).SingleOrDefault(o => o.IdProduct == 6);
Trace.WriteLine("Order: " + exprSingleOrDefaultWithoutMatchingElements);
Output:
Order:
Example 5:
var exprSingleOrDefaultWithSingleMathingElement = (from c in Data.Customers
from o in c.Orders
select o).SingleOrDefault(o => o.IdProduct == 2);
Trace.WriteLine("Order: " + exprSingleOrDefaultWithSingleMathingElement);
Output:
Order: 5 – True – May – 2
The ElementAt, (ElementAtOrDefault) operator extracts the element pointed by index. If the pointed index is greater or less than bounds of a sequence the ArgumentOutOfRangeExeption exception will be thrown. The ElementAtOrDefault operator doesn’t generate the ArgumentOutOfRangeExeption exception.
public static TSource ElementAt<TSource>(this IEnumerable<TSource> source, int index);
public static TSource ElementAtOrDefault<TSource>( this IEnumerable<TSource> source, int index);
Example 6:
Trace.WriteLine("ElementAt(5): " + Data.Customers.ElementAtOrDefault(5));
Trace.WriteLine("ElementAt(0): " + Data.Customers.ElementAtOrDefault(0));
Output:
ElementAt(5):
ElementAt(0): Paolo – Brescia – Italy
The DefaultIfEmpty operator supplies a default element for an empty sequence.
public static IEnumerable<TSource> DefaultIfEmpty<TSource>( this IEnumerable<TSource> source);
public static IEnumerable<TSource> DefaultIfEmpty<TSource>( this IEnumerable<TSource> source,
TSource defaultValue);
Example 7:
var customers = Enumerable.Empty<Customer>().DefaultIfEmpty(new Customer());
foreach (var item in customers)
{
Trace.WriteLine("Empty customer: " + item);
}
Output:
Empty customer: – – USA
Example 8:
var expr = from p in Data.Products
join o in
(
from c in Data.Customers
from o in c.Orders
select o
)
on p.IdProduct equals o.IdProduct into orders
select new { p.IdProduct, Orders = orders.DefaultIfEmpty(new Order()) };
foreach (var product in expr)
{
Trace.IndentLevel = 1;
Trace.WriteLine("ProductId: " + product.IdProduct);
Trace.Indent();
foreach (var order in product.Orders)
{
Trace.WriteLine("Order: " + order);
}
}
Output:
ProductId: 1
Order: 3 – False – January – 1
Order: 10 – False – July – 1
ProductId: 2
Order: 5 – True – May – 2
ProductId: 3
Order: 20 – True – December – 3
Order: 20 – True – December – 3
Order: 20 – True – December – 3
Order: 20 – True – December – 3
ProductId: 4
Order: 0 – False – – 0
ProductId: 5
Order: 20 – False – July – 5
ProductId: 6
Order: 0 – False – – 0