I've simplified a piece of a deferred execution code, but how on earth do you check the following is not null/empty without wrapping it in a try/catch?
string[] nullCollection = null;
IEnumerable<string> ienumerable = new[] { nullCollection }.SelectMany(a => a);
bool isnull = ienumerable == null; //returns false
bool isany = ienumerable.Any(); //throws an exception
You just need to make your lambda more resilient to null entries:
IEnumerable<string> ienumerable = new[] { nullCollection }
.SelectMany(a => a ?? Enumerable.Empty<string>());
bool isany = ienumerable.Any(); // Sets isany to 'false'
You cannot do that, because that's the same as asking "how can I tell that method will not throw NullReferenceException without invoking it?". Having no other clues the only way is actually invoke such methods and observe the result. Enumerating IEnumerable is just invoking bunch of MoveNext calls on it's enumerator, and any such call might throw any exceptions.
You can check if the current item from the enumerator is null
string[] nullCollection = null;
IEnumerable<string> ienumerable = new[] { nullCollection }.SelectMany(a => a);
bool isnull = ienumerable.GetEnumerator().Current == null;
if (!isnull)
{
bool isany = ienumerable.Any();
}
Since Linq methods are extension methods on IEnumerable, you could wrap these extensions further: with an extension method, the object receiving the extension can be null.
public static IEnumerable<TResult> SafeSelectMany<T, TCollection, TResult>(
this IEnumerable<T> source,
Func<T, IEnumerable<TCollection>> collectionSelector,
Func<T, TCollection, TResult> resultSelector)
{
if (source == null)
{
return null;
}
IEnumerable<TResult> result = source.SelectMany(collectionSelector, resultSelector);
return result;
}
You could also return an empty List<TResult> instead of null for source==null.
Related
Is it possible to use IEnumerable FirstOrDefault within a List extension method? I am getting the error 'List does not contain a definition for FirstOrDefault'?
using LanguageExt;
using System;
using System.Linq;
public static class Question
{
public static Option<T> Lookup<T>(this List<T> enumerable, Func<T, bool> predicate)
{
if (enumerable == null)
{
return Option<T>.None;
}
var val = enumerable.FirstOrDefault(predicate);
return val == null ? Option<T>.None : Option<T>.Some(val);
}
public static void Run()
{
bool isOdd(int i) => i % 2 == 1;
var none = new List<int>().Lookup(isOdd); // => None
var some = new List<int> { 1 }.Lookup(isOdd); // => Some(1)
}
}
Normally it is possible to use FirstOrDefault on any enumerable sequence, so also on Lists.
The following works:
Func<int, bool> predicate = isOdd;
List<int> integerSequence = new List<int>();
var a = integerSequence.FirstOrDefault();
var b = integerSequence.Where(i => predicate(i)).FirstOrDefault();
var c = integerSequence.FirstOrDefault(i => predicate(i));
So I can't reproduce your problem. I see other problems though.
If you don't understand the this keyword, read Extension Methods demystified. Whenever you think: damn, I wish they had thought of this LINQ method, consider creating an extension method.
So your Lookup method is an extension method that takes a list and a predicate as input.. Since it seems that it can work on any enumerable sequence, let's not limit ourselves to List<T>, let's accept any enumerable sequence, like Arrays, Dictionaries, Lookup-tables, etc.
Furthermore, LINQ methods are most reusable if you let them return a sequence or result items, and let your called decide whether he wants all items, or only the FirstOrDefault, or maybe the Last, or Average.
So if you decide to create an extension method that takes an enumerable sequence as input, let it return an Enumerable sequence whenever possible, even if the sequence is empty: avoid returning null, if you mean: there are no elements matching what you want. Because that would mean that callers should have to check the result before they can continue concatenating other LINQ methods.
Finally: LINQ methods usually don't except null sources as input, they throw exceptions. LINQ methods expect callers to make sure the input is not null. Of course you are free to deviate from this, but callers don't expect it when using LINQ like methods.
With these guidelines in mind, consider to change your extension method.
Apparently, if an element in your input sequence equals null, you want to return Option<T>.None, otherwise you want Option<T>.Some(val)
public static Option<T> ToOption<T>(this T sourceElement)
{
return sourceElement?.Option<T>.Some(sourceElement) ?? Option<T>.None;
}
In words: if sourceElement equals null, return Option<T>.Some(sourceElement), otherwise return Option<T>.None
In LINQ it is quite normal to create extension methods with equality comparers, this will make your methods even more reusable. Usually this will only need two or three lines of code:
public static Option<T> ToOption<T>(this T sourceElement)
{
return ToOption(sourceElement, null);
}
public static Option<T> ToOption<T>(
this T sourceElement,
IEqualityComparer<T> comparer)
{
if (comparer == null) comparer = EqualityComparer<T>.Default;
if (comparer.Equals(sourceElement, null)
return Option<T>.None;
else
return Option<T>.Some(sourceElement);
}
In the methods below I won't mention this possibility over and over again.
public static IEnumerable<Option<T>> ToOptions<T>(this IEnumerable<T> source)
{
// TODO: throw exception if input null
return source.Select(sourceElement => sourceElement.ToOption());
}
public static IEnumerable<Option<T>> ToOptions<T>(
this IEnumerable<T> source,
Func<T, bool> predicate)
{
// No need: check if source == null, this is done in the other ToOptions
// TODO: exception if predicate equals null
return source.Where(sourceElement => predicate(sourceElement))
.ToOptions();
}
Simple usage:
IEnumerable<Customer> customers = ...
MyClass myFirstEligableCustomer= customers
.ToOptions(customer => customer.Address.City == "New York")
.FirstOrDefault();
Or intertwined with other LINQ methods:
var result = customers.
.GroupBy(customer => customer.Birthday.Year)
.OrderBy(customerGroup => customerGroup.Key)
.ToOptions(customerGroup => customerGroup.Key)
.ToDictionary(customerGroup => customerGroup.Key, // Key
customerGroup => customerGroup.ToList); // Value
The result is a Dictionary, where the key is the Year of a birthday, and the value is the list of all Option<Customer> that are born in this year.
You see: most methods are barely more than one-liners. They are easy to reuse, easy to change, easy to test.
I was doing a custom Comparer to compare two classes in a Linq query like this one:
Table<Info> table = context.GetTable<Info>();
bool infoAlreadyExists = table.Contains(info, new MyComparer());
This is my comparer:
public class MyComparer : IEqualityComparer<Info>
{
#region IEqualityComparer<Info> Member
public bool Equals(Info x, Info y)
{
return x.Content == y.Content;
}
public int GetHashCode(Info obj)
{
return obj.Content.GetHashCode();
}
#endregion
}
The problem is that I get an exception. [System.NotSupportedException]
The exception tells me that a not supported overload for the Contains operator was found. Do I do something wrong or is it really NotSupported? I couldn't find anything on the documentation.
This is the definition of the overload I am trying to use of the contains method.
public static bool Contains<TSource>(this IQueryable<TSource> source, TSource item, IEqualityComparer<TSource> comparer);
That version of Contains method is not supported.You can see the full list here:
Supported and Unsupported LINQ Methods (LINQ to Entities)
So you need to perform this operation in memory, you can use AsEnumerable for that.
But in this case it seems you don't need that equality comparer. You can just use the below query to get the same result:
table.FirstOrDefault(x => x.Content == info.Content) != null;
I am very curious to know how to modify an existing LINQ function to add Func<T> TResult to the function signature, i.e. allow it to use a selector as in (o => o.CustomField).
For example, in C#, I can use .IsDistinct() to check if a list of integers are distinct. I can also use .IsDistinctBy(o => o.SomeField) to check if the integers in field o.SomeField are distinct. I believe that, behind the scenes, .IsDistinctBy(...) has something like the function signature Func<T> TResult appended to it?
My question is this: what is the technique for taking an existing LINQ extension function, and converting it so it can have a parameter (o => o.SomeField)?
Here is an example.
This extension function checks to see if a list is increasing monotonically (i.e. values are never decreasing, as in 1,1,2,3,4,5,5):
main()
{
var MyList = new List<int>() {1,1,2,3,4,5,5};
DebugAssert(MyList.MyIsIncreasingMonotonically() == true);
}
public static bool MyIsIncreasingMonotonically<T>(this List<T> list) where T : IComparable
{
return list.Zip(list.Skip(1), (a, b) => a.CompareTo(b) <= 0).All(b => b);
}
If I want to add a "By", I add a parameter Func<T> TResult. But how do I modify the body of the function to make it select by (o => o.SomeField)?
main()
{
DebugAssert(MyList.MyIsIncreasingMonotonicallyBy(o => o.CustomField) == true);
}
public static bool MyIsIncreasingMonotonicallyBy<T>(this List<T> list, Func<T> TResult) where T : IComparable
{
// Question: How do I modify this function to make it
// select by o => o.CustomField?
return list.Zip(list.Skip(1), (a, b) => a.CompareTo(b) <= 0).All(b => b);
}
Consider an implementation like the following, which enumerates the given IEnumerable<T> only once. Enumerating can have side-effects, and callers typically expect a single pass-through if that's possible.
public static bool IsIncreasingMonotonically<T>(
this IEnumerable<T> _this)
where T : IComparable<T>
{
using (var e = _this.GetEnumerator())
{
if (!e.MoveNext())
return true;
T prev = e.Current;
while (e.MoveNext())
{
if (prev.CompareTo(e.Current) > 0)
return false;
prev = e.Current;
}
return true;
}
}
Your enumerable.IsIncreasingMonotonicallyBy(x => x.MyProperty) overload that you describe can now be written as follows.
public static bool IsIncreasingMonotonicallyBy<T, TKey>(
this IEnumerable<T> _this,
Func<T, TKey> keySelector)
where TKey : IComparable<TKey>
{
return _this.Select(keySelector).IsIncreasingMonotonically();
}
Just apply the Func to a and b:
public static bool MyIsIncreasingMonotonicallyBy<T, TResult>(this IEnumerable<T> list, Func<T, TResult> selector)
where TResult : IComparable<TResult>
{
return list.Zip(list.Skip(1), (a, b) => selector(a).CompareTo(selector(b)) <= 0).All(b => b);
}
One above is close to right but there are issues:
Your list has possible multiple enumeration of IEnumeration
public static bool MyIsIncreasingMonotonicallyBy<T, TResult>(
this IEnumerable<T> list, Func<T, TResult> selector)
where TResult : IComparable<TResult>
{
var enumerable = list as IList<T> ?? list.ToList();
return enumerable.Zip(
enumerable.Skip(1),
(a, b) => selector(a).CompareTo(selector(b)) <= 0
).All(b => b);
}
P.S. I believe you need to remove the "this" because Extension method can only be declared in non-generic, non-nested static class.
In response to Frédéric Hamidi:
Consider the following:
IEnumerable<string> names = GetNames();
foreach (var name in names) Console.WriteLine("Found " + name);
var allNames = new StringBuilder();
foreach (var name in names) allNames.Append(name + " ");
Assuming that GetNames() returns an IEnumerable, we are, effectively, doing extra work by enumerating this collection twice in the two foreach statements. If GetNames() results in a database query, you end up doing that query twice, while both times getting the same data.
This kind of problem can be easily fixed – simply force the enumeration at the point of variable initialization by converting the sequence to a list(or you could do array). Both array and list types implement the IEnumerable interface.
Let's say I have the following method:
public static int CountNonNullMembers<T>(this IEnumerable<T> enumerable)
{
if (enumerable == null) throw new ArgumentNullException("enumerable");
int count = 0;
foreach (var x in enumerable)
{
if (x != null) count++;
}
return count;
}
And I have these 3 arrays::
var ints = Enumerable.Range(0,10).ToArray();
var nullableInts = Array.ConvertAll(ints,x=>x as int?);
var strings = Array.ConvertAll(ints,x => x.ToString());
I wrote a little function to do a loop and time it for a million iterations. Applying it to ints and strings, it finishes in about 100 ms on my machine. For nullableInts, it takes 2.5 seconds.
As I understand the check for null on int doesn't make sense, so the compiler has a different template for non-nullable struct types, that removes null checks. But Nullable<T> does not have a template that converts the null check to x.HasValue. If I have an unconstrained function, how can I do a null check that will perform well? I can't use EqualityComparer<T>, as null might not be a member of T as there is no constraint.
Also it's impossible to have overloads that differ by constraint, so I can't, say, have one for structs, one for Nullable<T>, and one for classes.
The caller of the method is non-constrained. This is just an example (not the actual method); the method calling is non-constrained. I need to do some work against non-null members, and it's a generic method. I suppose I could write a version that doesn't do the check vs one that does (and consequently has a different signature), but it's seems very ugly and unneeded.
Also, the extension method .Count inexplicably performs horribly for NullableInts and strings, (equally bad), so it really isn't the right approach. This might be the delegate invocation, but I doubt it. Using the UnboxT style method of Check<T>.IfNull performs a lot better.
Okay, really weird switching the body of the count to this performs great:
public static int CountNonNullMembers<T>(this IEnumerable<T> enumerable)
{
return enumerable.Count(Check<T>.IfNull.Invoke);
}
Why?
You can constrain generic type parameters to reference types or values types:
public static int CountNonNull<T>(this IEnumerable<T> source)
where T : class
{
return source.Count(x => x != null);
}
public static int CountNonNull<T>(this IEnumerable<Nullable<T>> source)
where T : struct
{
return source.Count(x => x.HasValue);
}
You don't need an overload for non-nullable structs, because they can't be null anyway.
Using the UnboxT approach works. But I'd also like something that doesn't require creating a static type::
public static class Check<T>
{
public static readonly Predicate<T> IfNull = CreateIfNullDelegate();
private static bool AlwaysFalse(T obj)
{
return false;
}
private static bool ForRefType(T obj)
{
return object.ReferenceEquals(obj, null);
}
private static bool ForNullable<Tu>(Tu? obj) where Tu:struct
{
return !obj.HasValue;
}
private static Predicate<T> CreateIfNullDelegate()
{
if (!typeof(T).IsValueType)
return ForRefType;
else
{
Type underlying;
if ((underlying = Nullable.GetUnderlyingType(typeof(T))) != null)
{
return Delegate.CreateDelegate(
typeof(Predicate<T>),
typeof(Check<T>)
.GetMethod("ForNullable",BindingFlags.NonPublic | BindingFlags.Static)
.MakeGenericMethod(underlying)
) as Predicate<T>;
}
else
{
return AlwaysFalse;
}
}
}
}
Using this approach everything performs about the same. Strings performs worse, but not so much worse than everything else.
While not necessarily better than your method, it doesn't require a whole class:
static Dictionary<Type, object> NullChecks = new Dictionary<Type, object>();
public static Func<T, bool> MakeNullCheck<T>()
{
object obj;
Func<T, bool> func;
if (NullChecks.TryGetValue(typeof(T), out obj))
return (Func<T, bool>)obj;
if (typeof(T).IsClass)
func = x => x != null;
else if (Nullable.GetUnderlyingType(typeof(T)) != null)
{
var param = Expression.Parameter(typeof(T));
func = Expression.Lambda<Func<T, bool>>(
Expression.Property(param, typeof(T).GetProperty("HasValue")), param).Compile();
}
else
func = x => false;
NullChecks[typeof(T)] = func;
return func;
}
Just for curiosity/convenience: C# provides two cool conditional expression features I know of:
string trimmed = (input == null) ? null : input.Trim();
and
string trimmed = (input ?? "").Trim();
I miss another such expression for a situation I face very often:
If the input reference is null, then the output should be null. Otherwise, the output should be the outcome of accessing a method or property of the input object.
I have done exactly that in my first example, but (input == null) ? null : input.Trim() is quite verbose and unreadable.
Is there another conditional expression for this case, or can I use the ?? operator elegantly?
Something like Groovy's null-safe dereferencing operator?
string zipCode = customer?.Address?.ZipCode;
I gather that the C# team has looked at this and found that it's not as simple to design elegantly as one might expect... although I haven't heard about the details of the problems.
I don't believe there's any such thing in the language at the moment, I'm afraid... and I haven't heard of any plans for it, although that's not to say it won't happen at some point.
EDIT: It's now going to be part of C# 6, as the "null-conditional operator".
Currently we can only write an extension method if you don't want to repeat yourself, I'm afraid.
public static string NullableTrim(this string s)
{
return s == null ? null : s.Trim();
}
You can choose between a custom Nullify class or a NullSafe extension method as described here: http://qualityofdata.com/2011/01/27/nullsafe-dereference-operator-in-c/
The usage will be as follows:
//Groovy:
bossName = Employee?.Supervisor?.Manager?.Boss?.Name
//C# Option 1:
bossName = Nullify.Get(Employee, e => e.Supervisor, s => s.Manager,
m => m.Boss, b => b.Name);
//C# Option 2:
bossName = Employee.NullSafe( e => e.Supervisor ).NullSafe( s => s.Boss )
.NullSafe( b => b.Name );
As a workaround you can use this which is based on Maybe monad.
public static Tout IfNotNull<Tin, Tout>(this Tin instance, Func<Tin, Tout> Output)
{
if (instance == null)
return default(Tout);
else
return Output(instance);
}
Use it this way:
int result = objectInstance.IfNotNull(r => 5);
var result = objectInstance.IfNotNull(r => r.DoSomething());
There's nothing built-in, but you could wrap it all up in an extension method if you wanted (although I probably wouldn't bother).
For this specific example:
string trimmed = input.NullSafeTrim();
// ...
public static class StringExtensions
{
public static string NullSafeTrim(this string source)
{
if (source == null)
return source; // or return an empty string if you prefer
return source.Trim();
}
}
Or a more general-purpose version:
string trimmed = input.IfNotNull(s => s.Trim());
// ...
public static class YourExtensions
{
public static TResult IfNotNull<TSource, TResult>(
this TSource source, Func<TSource, TResult> func)
{
if (func == null)
throw new ArgumentNullException("func");
if (source == null)
return source;
return func(source);
}
}
I had the same problem I wrote a few little extension methods:
public static TResult WhenNotNull<T, TResult>(
this T subject,
Func<T, TResult> expression)
where T : class
{
if (subject == null) return default(TResult);
return expression(subject);
}
public static TResult WhenNotNull<T, TResult>(
this T subject, Func<T, TResult> expression,
TResult defaultValue)
where T : class
{
if (subject == null) return defaultValue;
return expression(subject);
}
public static void WhenNotNull<T>(this T subject, Action<T> expression)
where T : class
{
if (subject != null)
{
expression(subject);
}
}
You use it like this;
string str = null;
return str.WhenNotNull(x => x.Length);
or
IEnumerable<object> list;
return list.FirstOrDefault().WhenNotNull(x => x.id, -1);
or
object obj;
IOptionalStuff optional = obj as IOptionalStuff;
optional.WhenNotNull(x => x.Do());
There are also overloads for nullable types.
I know this was already answered by Jon Skeet but this example might be a little more clear example of the Elvis operator ?. (aka the null-conditional member access operator)
string? someValue = (input == null) ? null : input.Trim()
is equivalent to...
string? someValue = input?.Trim();
"Thank You, Thank You Very Much" - Elvis Presley