Replies: 43 comments 1 reply
-
You can already write: if ( (Car.Make("Benz").Body.Wheels.Count is var wheels) && (wheels == 4 || wheels == 3) )
// Do something... |
Beta Was this translation helpful? Give feedback.
-
We had a discussion about a similar feature (partial infix expressions) in #812. |
Beta Was this translation helpful? Give feedback.
-
I just recently asked for something similar and learned a nice way to do it:
I want to point out that "is var" is not the same as "is ". IsVar always returns true and always assigns a value to the following variable. Is only returns true if it can assign a non-null value. |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
@mattwar that's pretty cool I didn't know about that, but In my opinion it is the same amount of code and it looks more confusing than declaring a new variable. |
Beta Was this translation helpful? Give feedback.
-
This can be worked around using if (Car.Make("Benz").Body.Wheels.Count is var wheelsCount && wheelsCount == 4 || wheelsCount == 3) but it's long-winded. Allowing if (Car.Make("Benz").Body.Wheels.Count as var wheelsCount == 4 || wheelsCount == 3) |
Beta Was this translation helpful? Give feedback.
-
Am I alone thinkinh that using I'd like more idea about expression |
Beta Was this translation helpful? Give feedback.
-
It's not Either way, it's in the language already. And you already have an expression Conversely, you already have a blocked |
Beta Was this translation helpful? Give feedback.
-
@HaloFour when I'm taling about blocking if I'm talking about if's like in Rust let big_n =
if n < 10 && n > -10 {
println!("n is a small number, increase ten-fold");
10 * n
} else {
println!("n is a big number, reduce by two");
n / 2
}; Today I'm trying to extract a method where I can but it's not always possible/preferable.
I was never understanding this |
Beta Was this translation helpful? Give feedback.
-
In Rust all statements are either declarations or expressions. That is not the case in C# and it wouldn't make sense to try to force it onto C#.
Sets the foundation for recursive patterns where some other part of the pattern might not succeed. Or it could be combined with pattern guards to filter based on more complex logic that can't be directly mapped to a pattern. The use case described in this proposal isn't a wrong use of the Note that Rust has top-level always-matching variable bindings also: let x = 1;
match x {
y => println!("x: {} y: {}", x, y),
} |
Beta Was this translation helpful? Give feedback.
-
Do not substitute concepts, I'm talking about extensing
It's just my IMHO that that's a misuse of the feature. No more, no less.
Could you provide an example, please? |
Beta Was this translation helpful? Give feedback.
-
One example of recursive patterns would be with tuples: (bool succss, int value) TryParse(string s) ...
if (TryParse("123") is var (success, value) && success)
{
// use value here |
Beta Was this translation helpful? Give feedback.
-
You're the one who mentioned expression Take a look at #377, that would enable the scenario that you described: var big_n = (n < 10 && n > -10)
? (Console.WriteLine(", and is a small number, increase ten-fold"); 10 * n)
: (Console.WriteLine(", and is a big number, reduce by two"); n / 2); |
Beta Was this translation helpful? Give feedback.
-
I doubt you are alone, but I disagree it's a broken idea. I have to confess, I haven't found a use for SomeType Foo(IEnumerable<T> collection) =>
collection is List<T> list ? HandleAsList(list) : HandleAsEnumerable(collection); |
Beta Was this translation helpful? Give feedback.
-
@DavidArno this example is completely valid. I'm talking about some bizzare things like: SomeType Foo() =>
new int[1,2,3] is var collection ? HandleAsEnumerable(collection) : null; instead of SomeType Foo()
{
var collection = new int[1,2,3];
HandleAsEnumerable(collection);
} just because it's singleline. Here is plenty example in issues where they are using just to copy a value: SomeType Foo()
{
var collection = new int[1,2,3];
if (collection is var collectionCopy)
{
HandleAsEnumerable(collectionCopy);
}
} or more realistic example: if ( (Car.Make("Benz").Body.Wheels.Count is var wheels) && (wheels == 4 || wheels == 3) ) and so on. |
Beta Was this translation helpful? Give feedback.
-
I believe he means that he's using the "leaky" scope to write validation code where he intends the variable to remain usable: if (!(arg is Foo foo))
throw new ArgumentException($"{nameof(arg)} ain't no Foo!");
foo.Pity(); |
Beta Was this translation helpful? Give feedback.
-
@DavidArno @HaloFour yes, particularly when there are many early exit conditions or when Also, I dislike leaving the last line of a method a |
Beta Was this translation helpful? Give feedback.
-
See, corefx does this even more than me: |
Beta Was this translation helpful? Give feedback.
-
Here's a similar example with more detail, using |
Beta Was this translation helpful? Give feedback.
-
Oops, missed that I didn't need to assign |
Beta Was this translation helpful? Give feedback.
-
Thanks, makes sense now. Ask me again in a year and I may have changed my mind. In the meantime, I still think it an ugly pattern and the leakiness is too high a price to pay for convenience. If var topLevel = enumTypeReference as TopLevelTypeReference;
if (topLevel == null) throw(...
// use topLevel here. |
Beta Was this translation helpful? Give feedback.
-
It ends up feeling like a lot of repeated two-statement boilerplate to me. But who knows, maybe in another year I'll agree with you. =D |
Beta Was this translation helpful? Give feedback.
-
An extension method would do the trick: |
Beta Was this translation helpful? Give feedback.
-
@jcouv |
Beta Was this translation helpful? Give feedback.
-
Read this whole thing hoping for a revelation, but I'm sad to say I'm still with @Pzixel here. if (Car.Make("Benz").Body.Wheels.Count is var wheels && wheels == 4 || wheels == 3)
if (true && wheels = 4 || wheels == 3)
var success = int.TryParse("42", out i);
if (!success) return; and it would have been tree lines instead of two with no pattern matching. I really love that pattern matching enables declaration and initialization to go on one line. I don't care about declaration+initialization+(first use). Same applies to the recursive patterns example: var (success, value) = TryParse("123");
if (success) {... I generally love where C# syntax is going, and I'm adopting new features early, but in this case the old syntax is clearer for the same amount of keystrokes.
Speaking of the original issue, I always wanted a ternary math-like less-than: if (18 < age && age < 72) => if (18 < age < 72) with all the variations of course
Didn't give it a proper thought though. Hopefully there's no ambiguous syntax resulting from these ternary operators. |
Beta Was this translation helpful? Give feedback.
-
Why not use a switch (Car.Make("Benz").Body.Wheels.Count)
{
case 3: case 4:
//Do something...
break;
} |
Beta Was this translation helpful? Give feedback.
-
If all you need to do is test against a few const values, you could go with a ...
//usage
if (42.Is(InRange(30, 50).Or(InRange(100, 200))));
...
public static class BoolExpressionExtensions
{
public static bool Is<T>(this T value, params Predicate<T>[] predicates) =>
predicates.All(p => p(value));
public static Predicate<T> InRange<T>(T rangeMin, T rangeMax)
where T:IComparable<T> =>
value => value.CompareTo(rangeMin) >= 0 &&
value.CompareTo(rangeMax) <= 0;
public static Predicate<T> Or<T> (this Predicate<T> predicateA, Predicate<T> predicateB) =>
v => predicateA(v) || predicateB(v);
} Is there a library for this? I couldn't find one, and I'm tempted to write one. |
Beta Was this translation helpful? Give feedback.
-
@calin-darie, not what you are looking for, but Fluent Assertions goes in a similar direction. |
Beta Was this translation helpful? Give feedback.
-
With pattern matching you can now just say: |
Beta Was this translation helpful? Give feedback.
-
I could have sworn one could do this today ever since C# 10: if ( Car.Make("Benz").Body.Wheels.Count is 3 or 4 )
//Do something... |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Lets say we have an if statement like below:
Since some times the properties chain can be long and we can have even more ors(||) added. it can get ugly. One solution is to introduce a variable.
Can we do something where in these cases we don't have to introduce a variable or have long ifs?
Here is an idea. Maybe someone else can have a better looking syntax.
Beta Was this translation helpful? Give feedback.
All reactions