I have the following extension methods:
public static IEnumerable<T?> From<T>(params T?[] values) {
return values.AsEnumerable();
}
public static IEnumerable<T> WhereNonNull<T>(this IEnumerable<T?> enumerable)
{
return enumerable.Where(x => x != null).Cast<T>();
}
I use it like this:
uint? parentId = ...;
int b = ...;
foreach(var boneId in CollectionUtils.From(parentId, (uint)b).WhereNonNull())
parentId is of type uint? and
I would expect boneId to be of type uint due to the Cast<T>(), but it actually is uint?.
Am I missing something?
You can achieve the desired behavior with the
structandnotnullconstraints.See Constraints on type parameters for details
For
uint?change theWhereNotNullmethod to:To support reference types as well also add
It all comes down to the difference between nullable value types (
Nullable<T>orT?for structs) and nullable reference typesT?(likeobject?):The
structconstraint will make sure thatTmust be a non-nullable value type. So in this caseT?meansNullable<T>In
notnullconstraint that the value will be a non-nullable reference or non-nullable value type. The behavior of this method is the same as the version without constraints when there is no overload withstructconstraint available. You would only need it if you want to support bothNullable<T>and nullable reference types at the same time.