Replies: 8 comments
-
Real world version of example 3 that I wanted today: var log = condition ? logger.WarnFormat : logger.ErrorFormat;
log(... many args ...) |
Beta Was this translation helpful? Give feedback.
-
Another real-world example: public class Mock<T> {
public IEnumerable<TArgument> GetArgumentsFromAllCalls<TArgument, TResult>(
Func<T, Func<TArgument, TResult>> method
) { ... }
} var mock = new Mock<IComparable>();
...
// does not work
var args = mock.GetArgumentsFromAllCalls(c => c.CompareTo);
// does work
var args = mock.GetArgumentsFromAllCalls<object, int>(c => c.CompareTo); Since There are few other cases in mock libraries where it would come handy. |
Beta Was this translation helpful? Give feedback.
-
I love and completely support the proposal. However @eyalsk I can't agree that Expressions are 'rare' and should default to not using them (presumably not supporting them in the scope of the proposal). Having an EF-driven back-end (ie: ASP.NET / EF / Azure) we actually have Expressions everywhere, from helper query methods such as the below example to helper utilities - even aspects of our mocking/isolation infrastructure uses them outside of EF/LINQ. Expressions are super useful, not THAT rare if you use C#/.NET for any of its unique features (which the Expressions API is absolutely one of). Real-world C# 8 example:
|
Beta Was this translation helpful? Give feedback.
-
@marchy i suspect target typed switch expressions would help there .... |
Beta Was this translation helpful? Give feedback.
-
@marchy I'm not the original author of the proposal and because the original author didn't post it here I decided to do it, however, no one said they aren't useful and no one said that they are rare but in general expression might not be as common, I don't have the data to know whether this is the case so it's down to the language design team to decide what's the best approach to go about here if and when they will ever decide to do it. |
Beta Was this translation helpful? Give feedback.
-
When I first pointed it out it just felt really clunky to have to do be explicit with one of the switch cases when using switch expressions and returning a particular type. It feels like if every delegate in each switch case all have the same signature then the type should be inferred. For example: private Action Test(string name) => name switch {
"John" => () => Console.WriteLine("Hello John"),
"Jane" => () => Console.WriteLine("Hello Jane"),
_ => () => Console.WriteLine("Who are you?")
}; Since each case is returning a delegate with no parameters and a void return type, this should be legal. Instead I have to add something like the below to one of the cases to get it to compile () => new Action(() => Console.WriteLine("Hello John"), As long as each case has the same signature, regardless of the delegate signature, should type inference work? |
Beta Was this translation helpful? Give feedback.
-
@lkomanetz That code is legal, since the |
Beta Was this translation helpful? Give feedback.
-
@svick I was trying to recreate the scenario so I could see if there was something with project type or maybe language version that was different. I wasn't able to reproduce the issue on my current setup (running latest VS 2019). |
Beta Was this translation helpful? Give feedback.
-
Original post: #3990
The Action/Func delegate types have largely replaced custom delegates from the .NET 1.0 days. Action/Func should be considered the default delegate types if applicable.
C# should be able to implicitly convert method groups and lambda expressions to Delegate type. Also, method groups and lambda expressions should be converted to Action/Func whenever a concrete delegate type could not be derived otherwise.
Motivating examples:
None of these work as of C# 5. I think the language could be changed so that these example work naturally. The result should be that the Action/Func types be used implicitly.
There are cases where Action/Func do not apply. out and ref come to mind, so does variance. In those cases an error message should be emitted. Those cases are rare and we are not worse off than before.
Often, this will be ambiguous between
Func<...>
andExpression<Func<...>>
. Since expression tree usage is much rarer and tends to be more "expert-level" the default should beFunc<...>
.Beta Was this translation helpful? Give feedback.
All reactions