While it is common for new programmer to make this mistake of performing integer division when they actually meant to use floating point division, in actual practice integer division is a very common operation. If you are assuming that people rarely use it, and that every time you do division you'll always need to remember to cast to floating points, you are mistaken.
First off, integer division is quite a bit faster, so if you only need a whole number result, one would want to use the more efficient algorithm.
Secondly, there are a number of algorithms that use integer division, and if the result of division was always a floating point number you would be forced to round the result every time. One example off of the top of my head is changing the base of a number. Calculating each digit involves the integer division of a number along with the remainder, rather than the floating point division of the number.
Because of these (and other related) reasons, integer division results in an integer. If you want to get the floating point division of two integers you'll just need to remember to cast one to a double/float/decimal.
Module LambdaExt
<System.Runtime.CompilerServices.Extension> _
Public Function LeftJoin(Of TSource, TInner, TKey, TResult)(source As IEnumerable(Of TSource),
inner As IEnumerable(Of TInner),
pk As Func(Of TSource, TKey),
fk As Func(Of TInner, TKey),
result As Func(Of TSource, TInner, TResult)) As IEnumerable(Of TResult)
Dim _result As IEnumerable(Of TResult) = Enumerable.Empty(Of TResult)()
_result = From s In source
Group Join i In inner
On pk(s) Equals fk(i) Into joinData = Group
From left In joinData.DefaultIfEmpty()
Select result(s, left)
Return _result
End Function
<System.Runtime.CompilerServices.Extension> _
Public Function RightJoin(Of TSource, TInner, TKey, TResult)(source As IEnumerable(Of TSource), inner As IEnumerable(Of TInner), pk As Func(Of TSource, TKey), fk As Func(Of TInner, TKey), result As Func(Of TSource, TInner, TResult)) As IEnumerable(Of TResult)
Dim _result As IEnumerable(Of TResult) = Enumerable.Empty(Of TResult)()
_result = From i In inner
Group Join s In source
On fk(i) Equals pk(s) Into joinData = Group
From right In joinData.DefaultIfEmpty()
Select result(right, i)
Return _result
End Function
<System.Runtime.CompilerServices.Extension> _
Public Function FullOuterJoin(Of TSource, TInner, TKey, TResult)(source As IEnumerable(Of TSource),
inner As IEnumerable(Of TInner),
pk As Func(Of TSource, TKey),
fk As Func(Of TInner, TKey),
result As Func(Of TSource, TInner, TResult)) As IEnumerable(Of TResult)
Dim left = source.LeftJoin(inner, pk, fk, result).ToList()
Dim right = source.RightJoin(inner, pk, fk, result).ToList()
Return left.Union(right)
End Function
End Module
LambdaExt.cs Code (C#)
public static IEnumerable<TResult> LeftJoin<TSource, TInner, TKey, TResult>(this IEnumerable<TSource> source,
IEnumerable<TInner> inner,
Func<TSource, TKey> pk,
Func<TInner, TKey> fk,
Func<TSource, TInner, TResult> result)
{
IEnumerable<TResult> _result = Enumerable.Empty<TResult>();
_result = from s in source
join i in inner
on pk(s) equals fk(i) into joinData
from left in joinData.DefaultIfEmpty()
select result(s, left);
return _result;
}
public static IEnumerable<TResult> RightJoin<TSource, TInner, TKey, TResult>(this IEnumerable<TSource> source,
IEnumerable<TInner> inner,
Func<TSource, TKey> pk,
Func<TInner, TKey> fk,
Func<TSource, TInner, TResult> result)
{
IEnumerable<TResult> _result = Enumerable.Empty<TResult>();
_result = from i in inner
join s in source
on fk(i) equals pk(s) into joinData
from right in joinData.DefaultIfEmpty()
select result(right, i);
return _result;
}
public static class LinqExtension
{
public static IEnumerable<TResult> LeftJoin<TSource, TInner, TKey, TResult>(this IEnumerable<TSource> source,
IEnumerable<TInner> inner,
Func<TSource, TKey> primaryKey,
Func<TInner, TKey> foreignKey,
Func<TSource, TInner, TResult> resultCollection)
{
var result = from s in source
join i in inner
on primaryKey(s) equals foreignKey(i) into joinData
from left in joinData.DefaultIfEmpty()
select resultCollection(s, left);
return result;
}
public static IEnumerable<TResult> RightJoin<TSource, TInner, TKey, TResult>(this IEnumerable<TSource> source,
IEnumerable<TInner> inner,
Func<TSource, TKey> primaryKey,
Func<TInner, TKey> foreignKey,
Func<TSource, TInner, TResult> resultCollection)
{
var result = from i in inner
join s in source
on foreignKey(i) equals primaryKey(s) into joinData
from right in joinData.DefaultIfEmpty()
select resultCollection(right, i);
return result;
}
public static IEnumerable<TResult> FullOuterJoin<TSource, TInner, TKey, TResult>(this IEnumerable<TSource> source,
IEnumerable<TInner> inner,
Func<TSource, TKey> primaryKey,
Func<TInner, TKey> foreignKey,
Func<TSource, TInner, TResult> resultCollection)
{
IEnumerable<TSource> sourceCollection = source as IList<TSource> ?? source.ToList();
IEnumerable<TInner> innerCollection = inner as IList<TInner> ?? inner.ToList();
var left = sourceCollection.LeftJoin(innerCollection, primaryKey, foreignKey, resultCollection).ToList();
var right = sourceCollection.RightJoin(innerCollection, primaryKey, foreignKey, resultCollection).ToList();
return left.Union(right);
}
public static IEnumerable<TResult> LeftExcludingJoin<TSource, TInner, TKey, TResult>(this IEnumerable<TSource> source,
IEnumerable<TInner> inner,
Func<TSource, TKey> primaryKey,
Func<TInner, TKey> foreignKey,
Func<TSource, TInner, TResult> resultCollection)
{
var result = from s in source
join i in inner
on primaryKey(s) equals foreignKey(i) into joinData
from left in joinData.DefaultIfEmpty()
where left == null
select resultCollection(s, left);
return result;
}
public static IEnumerable<TResult> RightExcludingJoin<TSource, TInner, TKey, TResult>(this IEnumerable<TSource> source,
IEnumerable<TInner> inner,
Func<TSource, TKey> primaryKey,
Func<TInner, TKey> foreignKey,
Func<TSource, TInner, TResult> resultCollection)
{
var result = from i in inner
join s in source
on foreignKey(i) equals primaryKey(s) into joinData
from right in joinData.DefaultIfEmpty()
where right == null
select resultCollection(right, i);
return result;
}
public static IEnumerable<TResult> FullOuterExcludingJoin<TSource, TInner, TKey, TResult>(this IEnumerable<TSource> source,
IEnumerable<TInner> inner,
Func<TSource, TKey> primaryKey,
Func<TInner, TKey> foreignKey,
Func<TSource, TInner, TResult> resultCollection)
{
IEnumerable<TSource> sourceCollection = source as IList<TSource> ?? source.ToList();
IEnumerable<TInner> innerCollection = inner as IList<TInner> ?? inner.ToList();
var left = sourceCollection.LeftExcludingJoin(innerCollection, primaryKey, foreignKey, resultCollection).ToList();
var right = sourceCollection.RightExcludingJoin(innerCollection, primaryKey, foreignKey, resultCollection).ToList();
return left.Union(right);
}
}