-
Notifications
You must be signed in to change notification settings - Fork 4.1k
This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
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
Proposal: inverted null-coalesce operator ?! #15823
Comments
I personally think, that it is a wonderful idea, I do however dislike the token I would like to see the pipe-operator |
Ah, never thought of that scenario, nice! What token to use is of no big importance to me though. You may be able to flip it around to My initial thought of I like How about |
Using existing features: string possibleIntInput = ...
int? possibleIntValue = possibleIntInput?.ParseInt32();
static int? ParseInt32(this string str) { ... } |
Or with a generic helper function: static TResult Do<TInput, TResult>(this TInput input, Func<TInput, TResult> func)
{
return func(input);
}
string possibleIntInput = ...
int? possibleIntValue = possibleIntInput?.Do(int.Parse); |
Yes, it is possible to "overcome" this using extension methods. However, I don't find extension methods as expressive, and, if I were to start passing delegates around I'd have to check them for null too. It's not ideal! |
Just a crazy idea but what do you think about the following syntax:
|
I'm all for it as long as it works with the rest of C#! (: |
Yeah it's a bit tricky. 😄 |
int? possibleIntValue =
from x in possibleIntInput
select int.Parse(x); The only problem is, this doesn't work because nullable value and reference types don't mix until/unless we get nullable reference types in C# vNext. |
Also, |
@niklaskallander Yes, but is |
@orthoxerox Again, am I missing something? |
@niklaskallander it's possible to implement |
You can do nearly the same with an extension method: using System;
static class Extensions
{
public static TResult Apply<T1, TResult>(this T1 x, Func<T1, TResult> f) => f(x);
}
class Program
{
static int? F(string s) => s?.Apply(int.Parse);
} |
@ufcpp Using extension methods has already been proposed by @qrli a few comments ago, and as I replied to his proposal: Extension methods are not as expressive and passing delegates gives you more stuff to null-check. It's not ideal! @orthoxerox Now I follow, thanks for explaining! Unfortunately, as with all other proposals using extension methods (which this also is but with some sugar on top), it's not as expressive and the linq syntax is too verbose for my liking. |
It's possible that I'm focusing too much on the example here, rather than the syntax proposal. But the example line: int? possibleIntValue = possibleIntInput ?! int.Parse(possibleIntInput); worries me. If I'd prefer to see the team focusing on pattern matching and unions, so an Option<int> possibleIntValue = int.TryParse(possibleIntInput); which would yield |
@DavidArno Thanks for your comment. The example is not there for demonstrating the problem I want to solve with the proposal, it is there to demonstrate the syntax of the proposal. A better example might be:
But as @Unknown6656 said a few comments above the token
With language features for both null-coalescing and null propagation I feel that this one is missing. (And, I'd also like to see more functional concepts in C# such as discriminated unions, immutable record types, forward piping etc.) |
@DavidArno Personally, I think that |
@eyalsk The thing with discriminated unions ( |
@niklaskallander I understand, I really hope for #5032. |
I don't see how that could create confusion: |
No it isn't. It's totally legal syntax today. It would be interpretted as:
|
I was thinking if the new operator was valid. Unfortunately it would break existing code like your example. |
@niklaskallander Proposed new language features should be discussed at the C# repo so you may want to close this and open a new issue there. |
If we're going for syntactic sugar then piping would surely be ideal because the reverse-coalescing would still require you to provide the input twice |
I often have the pattern of with this i could change it to so it'd be cool if the left hand side could treat false as nully (or null as falsey) |
I need this feature. But my proposition about alias is This means: when vendorId is Null then assign Null to car.vendor, otherwise get vendor by that vendorId. You can also write the same using |
|
and what does it do? My VS does not recognize it |
|
This is possible in JavaScript using the console.log(null && "Foo") // null
console.log({} && "Bar") // Bar I would say |
Bumping this up. Here is one use case example (presuming !? is new operator): return FirstName + (MiddleName !? $" {MiddleName}") + ' ' + LastName; |
Isnt effectively the same there? |
@drdamour - Try it. You may notice there's an extra space when there's no middle name. |
This is getting a little of topic. But, no, that's not the same because of the space @iricigor wants to insert a space before MiddleName if it isn't null. His example isn't the best example because there a thousand other ways to solve that problem, but that's not the point. PS. Here's one way: |
Ah yeah, missed the space. Nice example |
This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
I'd very much like to see a new operator in C# that kind of does the opposite of the null-coalesce operator
??
(like the null propagation operator?
but still different).Usage example:
If
possibleIntInput
isnull
, thennull
is returned otherwise an attempt is made to parse it (or whatever other thing you'd want to happen as long as the left-hand object/value is notnull
).Then you could avoid less expressive code like:
#5445 proposes forward piping with null propagation behavior, and I would love being able to write something like this (it's so expressive and functional-like):
but I don't just want forward piping, I also want a syntax for either
null
or{whatever code}
(that returns an object/value of whatever type is expected by the context).What do you think?
The text was updated successfully, but these errors were encountered: