Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SelectNonNull extension method #24851

Closed
Thaina opened this issue Jan 31, 2018 · 12 comments
Closed

SelectNonNull extension method #24851

Thaina opened this issue Jan 31, 2018 · 12 comments
Labels
api-suggestion Early API idea and discussion, it is NOT ready for implementation area-System.Linq
Milestone

Comments

@Thaina
Copy link

Thaina commented Jan 31, 2018

Could we have this in System.Linq ?

public static IEnumerable<V> SelectNonNull<T,V>(this IEnumerable<T> items,Func<T,V> func) where V : class
{
	foreach(var item in items)
	{
		var value = func(item);
		if(value != null)
			yield return value;
	}
}

public static IEnumerable<V> SelectNonNull<T,V>(this IEnumerable<T> items,Func<T,V?> func) where V : struct
{
	foreach(var item in items)
	{
		var value = func(item);
		if(value.HasValue)
			yield return value.Value;
	}
}

I don't know what name it should but this extension method is convenient

@OmarTawfik
Copy link
Contributor

OmarTawfik commented Feb 2, 2018

Thanks Thaina. It would be helpful to follow https:/dotnet/corefx/blob/master/Documentation/project-docs/api-review-process.md

Also, it would be helpful to mention the most common use cases, and why it is specially needed in the framework, and not as a helper library to a few users who might use it.

@jnm2
Copy link
Contributor

jnm2 commented Feb 16, 2018

SelectNonNull has always struck me as ugly. .Select(...).NonNull() is more interesting to me. More generally, it could be .Select(...).Except(null) where it's a more efficient single-item version of the existing Except.

@Thaina
Copy link
Author

Thaina commented Feb 16, 2018

@jnm2 Interesting. .ExceptNull() could be alternative

But Except(null) is not possible. Because Except(null) will match Except((IEnumerable)null). We need new name for it

And it can't convert nullable to struct, which is the point of this proposal

Also should we .Select(func).ExceptNull() or just allow .ExceptNull(func) ?

@stephentoub
Copy link
Member

Why is this not just:

.Select(func).Where(c => c != null)

?

@jnm2
Copy link
Contributor

jnm2 commented Jul 18, 2019

@stephentoub @Thaina seemed particularly interested in the unwrapping of nullable values (second overload).

Equivalent of that one would be .Select(func).Where(n => n != null).Select(n => n.Value)

I have a .Values() extension method which shows up for enumerables of nullables and returns an enumerable of the inner value type, and I do find that quite ergonomic.

@Thaina
Copy link
Author

Thaina commented Jul 19, 2019

@stephentoub It obviously shorter and reduce number of delegates

@stephentoub
Copy link
Member

It obviously shorter and reduce number of delegates

Yes, that's true for any LINQ usage of multiple operators; you could always create a new operator that represented the combination. I'm not seeing why this particular combination is so valuable and generally in need by many developers that it would warrant a dedicated method.

@Thaina
Copy link
Author

Thaina commented Jul 19, 2019

@stephentoub Because I think this is most common logic. To select something and also filtering at the same time. Without the need to pollute code with .Where(n => n != null) everywhere we could just indicate that we don't need null

@Connect-a
Copy link

If we have a NonNull (or FilterOutNull?), we can convert IEnumerable<int?> into IEnumerable<int>.
I want to processing list of nullable reference types more easily .

https://docs.microsoft.com/ja-jp/dotnet/csharp/tutorials/nullable-reference-types

@msftgits msftgits transferred this issue from dotnet/corefx Jan 31, 2020
@msftgits msftgits added this to the Future milestone Jan 31, 2020
@virzak
Copy link
Contributor

virzak commented Sep 23, 2020

I ran into the same need when converting code base of a project to NRT.

A pattern that keeps appearing in my code is:

public IEnumerable<Guid> GetAllGuids1(IEnumerable<SomeClass> instances)
{
    return instances
        .Where(x => x.SomeGuid.HasValue)
        .Select(x => x.SomeGuid!.Value);
}

public class SomeClass
{
    public Guid? SomeGuid { get; set; }
    public string? Name { get; set; }
}

Couldn't find anything in the framework which would allow to easily convert from T? to T without the use of null-forgiving operator. Eliminating the need for ! is what makes this combination valuable. @stephentoub

@stephentoub
Copy link
Member

Eliminating the need for ! is what makes this combination valuable

I don't think adding new LINQ APIs is the right way to address this. From my perspective, it should be done via language/compiler support.
dotnet/roslyn#39586
dotnet/csharplang#3868
cc: @jcouv

@eiriktsarpalis
Copy link
Member

This is effectively a duplicate of #30381. Closing this one to focus the conversation.

@ghost ghost locked as resolved and limited conversation to collaborators Feb 19, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
api-suggestion Early API idea and discussion, it is NOT ready for implementation area-System.Linq
Projects
None yet
Development

No branches or pull requests

8 participants