I'm pulling all of the advanced features together for this one, but haven't worked with generics or lambda expressions very much:
Here's example usage of the method I want to create:
MyClass mc = null;
int x = mc.TryGetOrDefault(z => z.This.That.TheOther); // z is a reference to mc
// the code has not failed at this point and the value of x is 0 (int's default)
// had mc and all of the properties expressed in the lambda expression been initialized
// x would be equal to mc.This.That.TheOther's value
Here's as far as I've gotten, but I'm not sure what to do with this expression object.
[1
Is this the sort of thing you're after?
public static TResult TryGetOrDefault<TSource, TResult>(this TSource obj, Func<TSource, TResult> expression)
{
if (obj == null)
return default(TResult);
try
{
return expression(obj);
}
catch(NullReferenceException)
{
return default(TResult);
}
}
What you are trying to do sounds like Maybe.
Project Description:
Maybe or IfNotNull using lambdas for deep expressions in C#
int? CityId= employee.Maybe(e=>e.Person.Address.City);
Update: There is more discussion about how best to accomplish this sort of thing at this question.
Here's what I was after:
public static TResult TryGetOrDefault<TSource, TResult>(this TSource obj, Func<TSource, TResult> function, TResult defaultResult = default(TResult))
{
try
{
defaultResult = function(obj);
}
catch (NullReferenceException) { }
return defaultResult;
}
Related
I've made this extension method (I know right now there's no exception checking etc, will be added once I'm sure the function is actually correct):
public static IEnumerable<TSource> ChangeProperty<TSource, TResult>(this IEnumerable<TSource> source,Expression<Func<TSource,TResult>> res, Func<TSource, TResult> changeProp)
{
Type type = typeof(TSource);
MemberExpression member = res.Body as MemberExpression;
var name = member.Member.Name;
foreach (var x in source)
{
var prop = type.GetProperty(name);
prop.SetValue(x, changeProp(x));
Console.WriteLine(prop.GetValue(x));
}
return source;
}
And is used in this context(Remove unwanted tags strips html tags out of a string):
_dc.EmailTemplates
.ChangeProperty(x=>x.Body,z=>RemoveUnwantedTags(z.Body))
.ToList();
But I don't like that I have to use a double lambda, one for getting the property name, and then one for executing the function. I don't know if it's my lack of understanding on how Expression<> works, or if im missing something really obvious but would really appreciate the help!
Similar to how ForEach is used in List<T> the desired functionality can be simplified to
public static IEnumerable<TSource> Apply<TSource>(this IEnumerable<TSource> source, Action<TSource> action) {
foreach (var item in source) {
action(item);
yield return item;
}
}
and used
_dc.EmailTemplates
.Apply(x => x.Body = RemoveUnwantedTags(x.Body))
.ToList();
This can also be used for multiple members by doing
_dc.EmailTemplates
.Apply(x => {
x.Body = RemoveUnwantedTags(x.Body);
x.SomeOtherMember = SomeOtherFunction(x.SomeOtherMember);
})
.ToList();
I'm producing a list of decimal values from a LINQ expression and I want the minimum non zero value. However it's entirely possible that the LINQ expression will result in an empty list.
This will raise an exception and there is no MinOrDefault to cope with this situation.
decimal result = (from Item itm in itemList
where itm.Amount > 0
select itm.Amount).Min();
How can I set the result to 0 if the list is empty?
What you want is this:
IEnumerable<double> results = ... your query ...
double result = results.MinOrDefault();
Well, MinOrDefault() does not exist. But if we were to implement it ourselves it would look something like this:
public static class EnumerableExtensions
{
public static T MinOrDefault<T>(this IEnumerable<T> sequence)
{
if (sequence.Any())
{
return sequence.Min();
}
else
{
return default(T);
}
}
}
However, there is functionality in System.Linq that will produce the same result (in a slightly different way):
double result = results.DefaultIfEmpty().Min();
If the results sequence contains no elements, DefaultIfEmpty() will produce a sequence containing one element - the default(T) - which you subsequently can call Min() on.
If the default(T) is not what you want, then you could specify your own default with:
double myDefault = ...
double result = results.DefaultIfEmpty(myDefault).Min();
Now, that's neat!
decimal? result = (from Item itm in itemList
where itm.Amount != 0
select (decimal?)itm.Amount).Min();
Note the conversion to decimal?. You'll get an empty result if there are none (just handle that after the fact - I'm mainly illustrating how to stop the exception). I also made "non-zero" use != rather than >.
The neatest in terms of just doing it once in a small amount code is, as already mentioned:
decimal result = (from Item itm in itemList
where itm.Amount > 0
select itm.Amount).DefaultIfEmpty().Min();
With casting itm.Amount to decimal? and obtaining the Min of that being the neatest if we want to be able to detect this empty condition.
If however you want to actually provide a MinOrDefault() then we can of course start with:
public static TSource MinOrDefault<TSource>(this IQueryable<TSource> source, TSource defaultValue)
{
return source.DefaultIfEmpty(defaultValue).Min();
}
public static TSource MinOrDefault<TSource>(this IQueryable<TSource> source)
{
return source.DefaultIfEmpty(defaultValue).Min();
}
public static TResult MinOrDefault<TSource, TResult>(this IQueryable<TSource> source, Expression<Func<TSource, TResult>> selector, TSource defaultValue)
{
return source.DefaultIfEmpty(defaultValue).Min(selector);
}
public static TResult MinOrDefault<TSource, TResult>(this IQueryable<TSource> source, Expression<Func<TSource, TResult>> selector)
{
return source.DefaultIfEmpty().Min(selector);
}
You now have a full set of MinOrDefault whether or not you include a selector, and whether or not you specify the default.
From this point on your code is simply:
decimal result = (from Item itm in itemList
where itm.Amount > 0
select itm.Amount).MinOrDefault();
So, while it's not as neat to begin with, it's neater from then on.
But wait! There's more!
Let's say you use EF and want to make use of the async support. Easily done:
public static Task<TSource> MinOrDefaultAsync<TSource>(this IQueryable<TSource> source, TSource defaultValue)
{
return source.DefaultIfEmpty(defaultValue).MinAsync();
}
public static Task<TSource> MinOrDefaultAsync<TSource>(this IQueryable<TSource> source)
{
return source.DefaultIfEmpty(defaultValue).MinAsync();
}
public static Task<TSource> MinOrDefaultAsync<TSource, TResult>(this IQueryable<TSource> source, Expression<Func<TSource, TResult>> selector, TSource defaultValue)
{
return source.DefaultIfEmpty(defaultValue).MinAsync(selector);
}
public static Task<TSource> MinOrDefaultAsync<TSource, TResult>(this IQueryable<TSource> source, Expression<Func<TSource, TResult>> selector)
{
return source.DefaultIfEmpty().MinAsync(selector);
}
(Note that I don't use await here; we can directly create a Task<TSource> that does what we need without it, and hence avoid the hidden complications await brings).
But wait, there's more! Let's say we're using this with IEnumerable<T> some times. Our approach is sub-optimal. Surely we can do better!
First, the Min defined on int?, long?, float? double? and decimal? already do what we want anyway (as Marc Gravell's answer makes use of). Similarly, we also get the behaviour we want from the Min already defined if called for any other T?. So let's do some small, and hence easily inlined, methods to take advantage of this fact:
public static TSource? MinOrDefault<TSource>(this IEnumerable<TSource?> source, TSource? defaultValue) where TSource : struct
{
return source.Min() ?? defaultValue;
}
public static TSource? MinOrDefault<TSource>(this IEnumerable<TSource?> source) where TSource : struct
{
return source.Min();
}
public static TResult? Min<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult?> selector, TResult? defaultValue) where TResult : struct
{
return source.Min(selector) ?? defaultValue;
}
public static TResult? Min<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult?> selector) where TResult : struct
{
return source.Min(selector);
}
Now let's start with the more general case first:
public static TSource MinOrDefault<TSource>(this IEnumerable<TSource> source, TSource defaultValue)
{
if(default(TSource) == null) //Nullable type. Min already copes with empty sequences
{
//Note that the jitter generally removes this code completely when `TSource` is not nullable.
var result = source.Min();
return result == null ? defaultValue : result;
}
else
{
//Note that the jitter generally removes this code completely when `TSource` is nullable.
var comparer = Comparer<TSource>.Default;
using(var en = source.GetEnumerator())
if(en.MoveNext())
{
var currentMin = en.Current;
while(en.MoveNext())
{
var current = en.Current;
if(comparer.Compare(current, currentMin) < 0)
currentMin = current;
}
return currentMin;
}
}
return defaultValue;
}
Now the obvious overrides that make use of this:
public static TSource MinOrDefault<TSource>(this IEnumerable<TSource> source)
{
var defaultValue = default(TSource);
return defaultValue == null ? source.Min() : source.MinOrDefault(defaultValue);
}
public static TResult MinOrDefault<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector, TResult defaultValue)
{
return source.Select(selector).MinOrDefault(defaultValue);
}
public static TResult MinOrDefault<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector)
{
return source.Select(selector).MinOrDefault();
}
If we're really bullish about performance, we can optimise for certain cases, just like Enumerable.Min() does:
public static int MinOrDefault(this IEnumerable<int> source, int defaultValue)
{
using(var en = source.GetEnumerator())
if(en.MoveNext())
{
var currentMin = en.Current;
while(en.MoveNext())
{
var current = en.Current;
if(current < currentMin)
currentMin = current;
}
return currentMin;
}
return defaultValue;
}
public static int MinOrDefault(this IEnumerable<int> source)
{
return source.MinOrDefault(0);
}
public static int MinOrDefault<TSource>(this IEnumerable<TSource> source, Func<TSource, int> selector, int defaultValue)
{
return source.Select(selector).MinOrDefault(defaultValue);
}
public static int MinOrDefault<TSource>(this IEnumerable<TSource> source, Func<TSource, int> selector)
{
return source.Select(selector).MinOrDefault();
}
And so on for long, float, double and decimal to match the set of Min() provided by Enumerable. This is the sort of thing where T4 templates are useful.
At the end of all that, we have just about as performant an implementation of MinOrDefault() as we could hope for, for a wide range of types. Certainly not "neat" in the face of one use for it (again, just use DefaultIfEmpty().Min()), but very much "neat" if we find ourselves using it a lot, so we have a nice library we can reuse (or indeed, paste into answers on StackOverflow…).
This approach will return the single smallest Amount value from itemList. In theory this should avoid multiple round trips to the database.
decimal? result = (from Item itm in itemList
where itm.Amount > 0)
.Min(itm => (decimal?)itm.Amount);
The null reference exception is no longer caused because we are using a nullable type.
By avoiding the use of executing methods such as Any before calling Min, we should only be making one trip to the database
If itemList is non-nullable (where DefaultIfEmpty gives 0) and you want null as a potential output value, you can use the lambda syntax as well:
decimal? result = itemList.Where(x => x.Amount != 0).Min(x => (decimal?)x);
decimal result;
try{
result = (from Item itm in itemList
where itm.Amount != 0
select (decimal?)itm.Amount).Min();
}catch(Exception e){
result = 0;
}
I'm not quite sure how to phrase this question but the scenario is as follows:
Say I have the following class:
public class SampleClass
{
public int Number { get; set; }
}
I know you can null coalesce the containing class:
SampleClass newSampleClass = possibleNullSampleClass ?? notNullSampleClass;
Is there any way to perform a sort of null coalesce on the property so I don't have to do this:
int? num = sampleClass != null ? new int?(sampleClass.Number) : 5;
It seems like it would be very useful to have something like a ??? operator to perform this check so I could do:
int? num = sampleClass.Number ??? 5;
Is anything like that possible in C#?
Currently there is no such an operator. But in C# 6 "safe-navigation" operator will appear and you'll be able to write
int number = sampleClass?.Number;
This code won't fail with NullRef even if sampleClass equals null. For now you can use the following extension method that extracts value from an object and encapsulates null-check:
public static TResult Maybe<TSource, TResult>(
this TSource source, Func<TSource, TResult> produceResult, Func<TResult> produceDefault)
where TSource : class
{
return source == null ? produceDefault() : produceResult(source);
}
and use it as follows:
int numberOrFive = sampleClass.Maybe(c => c.Number, () => 5);
There is no existing operator to do that. You have shown one perfectly acceptable way of handling the problem.
If you wanted, you could wrap the logic in a method, but I'm not sure if that'd actually be worth the effort or not:
public static TResult Access<TSource, TResult>(
TSource obj, Func<TSource, TResult> selector, TResult defaultIfNull)
where TSource : class
{
if (obj == null)
return defaultIfNull;
else
return selector(obj);
}
SampleClass sampleClass = null;
int num = Access(sampleClass, s => s.Number, 5);
(If you wanted, you could consider making that an extension method as well, although I personally am wary of extension methods on all classes. Also consider other names, such as Use.)
I'm going to propose a modification of Servy's post. I think his method would prove useful if it could handle the general case, where there can be a null anywhere up the object chain.
public static TResult Access<TSource, TResult>(
TSource obj, Func<TSource, TResult> selector, TResult defaultIfNull)
where TSource : class
{
TResult result;
try
{
result = selector(obj);
}
catch ( NullReferenceException)
{
result = defaultIfNull;
}
return result;
}
This way if you are trying to access
ZipCode = Customer.Address.ZipCode;
You are protected if either Customer or Address is null
You can't do that in C#. You need to explicitly test for nullity:
MyWidget x ;
int? v = x == null ? (int?)x.SomeProperty : (int?) null ;
If you really think it would be useful, you could log your suggestion at Microsoft Connect:
http://connect.microsoft.com/VisualStudio
I'm willing to be that they thought about it and decided it wasn't sufficiently useful to build into the language.
You can totally do this:
var x = (myObject ?? DefaultObject).Field;
And this...
var x = (myObject == null) ? myObject.Field : defaultValue;
This question already has answers here:
Is there any way to negate a Predicate?
(2 answers)
Closed 9 years ago.
Func<T, bool> expr = x => x.Prop != 1;
somelist = somelist.Where(expr);
So far so good. But I would like to negate expr like this:
somelist = somelist.Where(!expr);
Which result in a compile error: Cannot apply ! operator to operand of type Func<T, bool>.
Do I have to create another expression variable for this?
Func<T, bool> expr2 = x => x.Prop == 1;
Func<T, bool> expr = x => x.Prop != 1;
Func<T, bool> negativeExpr = value => !expr(value);
or
somelist = somelist.Where(value => !expr(value));
When using expression trees the following will do the trick:
Expression<Func<T, bool>> expr = x => x.Prop != 1;
var negativeExpr = Expression.Lambda<Func<T, bool>>(
Expression.Not(expr.Body),
expr.Parameters);
somelist = somelist.Where(negativeExpr);
To make your life easier, you can create the following extension methods:
public static Func<T, bool> Not<T>(
this Func<T, bool> predicate)
{
return value => !predicate(value);
}
public static Expression<Func<T, bool>> Not<T>(
this Expression<Func<T, bool>> expr)
{
return Expression.Lambda<Func<T, bool>>(
Expression.Not(expr.Body),
expr.Parameters);
}
Now you can do this:
somelist = somelist.Where(expr.Not());
I'm just going to throw this out there as a silly answer. Just to be clear: I would not do this, and I do not recommend that anyone does this. :)
I kind of wanted to see if it was possible to get the somelist.Where(!expr) syntax or something like it.
Well I succeeded, and I hate myself.
var expr = N.egatable<MyClass>(x => x.Prop != 1);
somelist = someList.Where(!expr);
The N.egatable was just a small convenience syntax helper and largely unnecessary (EDIT: I wanted to avoid having to explicitly define MyClass or somehow make the instantiation of the object wrapper hidden, but couldn't quite get there and thought maybe someone would have a better idea):
public static class N
{
public static Negator<T> egatable<T>(Func<T, bool> underlyingFunction)
{
return new Negator<T>(underlyingFunction);
}
}
Negator<T> is where the real "magic" happens:
public class Negator<T>
{
private Func<T, bool> UnderlyingFunction;
public Negator(Func<T, bool> underlyingFunction)
{
this.UnderlyingFunction = underlyingFunction;
}
public static implicit operator Func<T, bool>(Negator<T> neg)
{
return v => neg.UnderlyingFunction(v);
}
public static Negator<T> operator !(Negator<T> neg)
{
return new Negator<T>(v => !neg.UnderlyingFunction(v));
}
}
First the ! operator overload performs the function negation (just as in this answer), then the implicit conversion operator to Func<T, bool> lets it pass in to the Where extension method.
Perhaps very silly is you can keep flipping it back and forth like this:
somelist = someList.Where(!!expr);
somelist = someList.Where(!!!expr);
somelist = someList.Where(!!!!expr);
somelist = someList.Where(!!!!!expr);
somelist = someList.Where(!!!!!!expr); //oh my what
So again... please don't do this. :) Definitely stick to the proper/sane way of doing things as in Steven's answer.
EDIT: Here's an implementation using expressions which works the exact same way in terms of syntax usage. Not sure if it's "correct", and haven't tested it against Entity Framework:
public class ExpressionNegator<T>
{
private Expression<Func<T, bool>> UnderlyingExpression;
public ExpressionNegator(Expression<Func<T, bool>> underlyingExpression)
{
this.UnderlyingExpression = underlyingExpression;
}
public static implicit operator Func<T, bool>(ExpressionNegator<T> neg)
{
return neg.UnderlyingExpression.Compile();
}
public static implicit operator Expression<Func<T, bool>>(ExpressionNegator<T> neg)
{
return neg.UnderlyingExpression;
}
public static ExpressionNegator<T> operator !(ExpressionNegator<T> neg)
{
var originalExpression = neg.UnderlyingExpression;
Expression<Func<T, bool>> negatedExpression = originalExpression.Update(
Expression.Not(originalExpression.Body),
originalExpression.Parameters);
return new ExpressionNegator<T>(negatedExpression);
}
}
I'm producing a list of decimal values from a LINQ expression and I want the minimum non zero value. However it's entirely possible that the LINQ expression will result in an empty list.
This will raise an exception and there is no MinOrDefault to cope with this situation.
decimal result = (from Item itm in itemList
where itm.Amount > 0
select itm.Amount).Min();
How can I set the result to 0 if the list is empty?
What you want is this:
IEnumerable<double> results = ... your query ...
double result = results.MinOrDefault();
Well, MinOrDefault() does not exist. But if we were to implement it ourselves it would look something like this:
public static class EnumerableExtensions
{
public static T MinOrDefault<T>(this IEnumerable<T> sequence)
{
if (sequence.Any())
{
return sequence.Min();
}
else
{
return default(T);
}
}
}
However, there is functionality in System.Linq that will produce the same result (in a slightly different way):
double result = results.DefaultIfEmpty().Min();
If the results sequence contains no elements, DefaultIfEmpty() will produce a sequence containing one element - the default(T) - which you subsequently can call Min() on.
If the default(T) is not what you want, then you could specify your own default with:
double myDefault = ...
double result = results.DefaultIfEmpty(myDefault).Min();
Now, that's neat!
decimal? result = (from Item itm in itemList
where itm.Amount != 0
select (decimal?)itm.Amount).Min();
Note the conversion to decimal?. You'll get an empty result if there are none (just handle that after the fact - I'm mainly illustrating how to stop the exception). I also made "non-zero" use != rather than >.
The neatest in terms of just doing it once in a small amount code is, as already mentioned:
decimal result = (from Item itm in itemList
where itm.Amount > 0
select itm.Amount).DefaultIfEmpty().Min();
With casting itm.Amount to decimal? and obtaining the Min of that being the neatest if we want to be able to detect this empty condition.
If however you want to actually provide a MinOrDefault() then we can of course start with:
public static TSource MinOrDefault<TSource>(this IQueryable<TSource> source, TSource defaultValue)
{
return source.DefaultIfEmpty(defaultValue).Min();
}
public static TSource MinOrDefault<TSource>(this IQueryable<TSource> source)
{
return source.DefaultIfEmpty(defaultValue).Min();
}
public static TResult MinOrDefault<TSource, TResult>(this IQueryable<TSource> source, Expression<Func<TSource, TResult>> selector, TSource defaultValue)
{
return source.DefaultIfEmpty(defaultValue).Min(selector);
}
public static TResult MinOrDefault<TSource, TResult>(this IQueryable<TSource> source, Expression<Func<TSource, TResult>> selector)
{
return source.DefaultIfEmpty().Min(selector);
}
You now have a full set of MinOrDefault whether or not you include a selector, and whether or not you specify the default.
From this point on your code is simply:
decimal result = (from Item itm in itemList
where itm.Amount > 0
select itm.Amount).MinOrDefault();
So, while it's not as neat to begin with, it's neater from then on.
But wait! There's more!
Let's say you use EF and want to make use of the async support. Easily done:
public static Task<TSource> MinOrDefaultAsync<TSource>(this IQueryable<TSource> source, TSource defaultValue)
{
return source.DefaultIfEmpty(defaultValue).MinAsync();
}
public static Task<TSource> MinOrDefaultAsync<TSource>(this IQueryable<TSource> source)
{
return source.DefaultIfEmpty(defaultValue).MinAsync();
}
public static Task<TSource> MinOrDefaultAsync<TSource, TResult>(this IQueryable<TSource> source, Expression<Func<TSource, TResult>> selector, TSource defaultValue)
{
return source.DefaultIfEmpty(defaultValue).MinAsync(selector);
}
public static Task<TSource> MinOrDefaultAsync<TSource, TResult>(this IQueryable<TSource> source, Expression<Func<TSource, TResult>> selector)
{
return source.DefaultIfEmpty().MinAsync(selector);
}
(Note that I don't use await here; we can directly create a Task<TSource> that does what we need without it, and hence avoid the hidden complications await brings).
But wait, there's more! Let's say we're using this with IEnumerable<T> some times. Our approach is sub-optimal. Surely we can do better!
First, the Min defined on int?, long?, float? double? and decimal? already do what we want anyway (as Marc Gravell's answer makes use of). Similarly, we also get the behaviour we want from the Min already defined if called for any other T?. So let's do some small, and hence easily inlined, methods to take advantage of this fact:
public static TSource? MinOrDefault<TSource>(this IEnumerable<TSource?> source, TSource? defaultValue) where TSource : struct
{
return source.Min() ?? defaultValue;
}
public static TSource? MinOrDefault<TSource>(this IEnumerable<TSource?> source) where TSource : struct
{
return source.Min();
}
public static TResult? Min<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult?> selector, TResult? defaultValue) where TResult : struct
{
return source.Min(selector) ?? defaultValue;
}
public static TResult? Min<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult?> selector) where TResult : struct
{
return source.Min(selector);
}
Now let's start with the more general case first:
public static TSource MinOrDefault<TSource>(this IEnumerable<TSource> source, TSource defaultValue)
{
if(default(TSource) == null) //Nullable type. Min already copes with empty sequences
{
//Note that the jitter generally removes this code completely when `TSource` is not nullable.
var result = source.Min();
return result == null ? defaultValue : result;
}
else
{
//Note that the jitter generally removes this code completely when `TSource` is nullable.
var comparer = Comparer<TSource>.Default;
using(var en = source.GetEnumerator())
if(en.MoveNext())
{
var currentMin = en.Current;
while(en.MoveNext())
{
var current = en.Current;
if(comparer.Compare(current, currentMin) < 0)
currentMin = current;
}
return currentMin;
}
}
return defaultValue;
}
Now the obvious overrides that make use of this:
public static TSource MinOrDefault<TSource>(this IEnumerable<TSource> source)
{
var defaultValue = default(TSource);
return defaultValue == null ? source.Min() : source.MinOrDefault(defaultValue);
}
public static TResult MinOrDefault<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector, TResult defaultValue)
{
return source.Select(selector).MinOrDefault(defaultValue);
}
public static TResult MinOrDefault<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector)
{
return source.Select(selector).MinOrDefault();
}
If we're really bullish about performance, we can optimise for certain cases, just like Enumerable.Min() does:
public static int MinOrDefault(this IEnumerable<int> source, int defaultValue)
{
using(var en = source.GetEnumerator())
if(en.MoveNext())
{
var currentMin = en.Current;
while(en.MoveNext())
{
var current = en.Current;
if(current < currentMin)
currentMin = current;
}
return currentMin;
}
return defaultValue;
}
public static int MinOrDefault(this IEnumerable<int> source)
{
return source.MinOrDefault(0);
}
public static int MinOrDefault<TSource>(this IEnumerable<TSource> source, Func<TSource, int> selector, int defaultValue)
{
return source.Select(selector).MinOrDefault(defaultValue);
}
public static int MinOrDefault<TSource>(this IEnumerable<TSource> source, Func<TSource, int> selector)
{
return source.Select(selector).MinOrDefault();
}
And so on for long, float, double and decimal to match the set of Min() provided by Enumerable. This is the sort of thing where T4 templates are useful.
At the end of all that, we have just about as performant an implementation of MinOrDefault() as we could hope for, for a wide range of types. Certainly not "neat" in the face of one use for it (again, just use DefaultIfEmpty().Min()), but very much "neat" if we find ourselves using it a lot, so we have a nice library we can reuse (or indeed, paste into answers on StackOverflow…).
This approach will return the single smallest Amount value from itemList. In theory this should avoid multiple round trips to the database.
decimal? result = (from Item itm in itemList
where itm.Amount > 0)
.Min(itm => (decimal?)itm.Amount);
The null reference exception is no longer caused because we are using a nullable type.
By avoiding the use of executing methods such as Any before calling Min, we should only be making one trip to the database
If itemList is non-nullable (where DefaultIfEmpty gives 0) and you want null as a potential output value, you can use the lambda syntax as well:
decimal? result = itemList.Where(x => x.Amount != 0).Min(x => (decimal?)x);
decimal result;
try{
result = (from Item itm in itemList
where itm.Amount != 0
select (decimal?)itm.Amount).Min();
}catch(Exception e){
result = 0;
}