Comments (13)
If I understand correctly, the proposal is to add the bold text below to the spec section 7.6.6.2:
An extension method
Ci.Mj
is eligible if:
•Ci
is a non-generic, non-nested class
• The name ofMj
is identifier
•Mj
is accessible and applicable when applied to the arguments as a static method as shown above
• An implicit identity, reference, method group, anonymous function, or boxing conversion exists from expr to the type of the first parameter ofMj
.
from csharplang.
@alrz I see what you mean. Because the conversion target would need to be manifest for method selection to even occur.
I think there might be other ways that this could be made to work. Basically compiler black magic that considers the possible target types having the bespoke extension method, but it would be better if there were in fact a default delegate type, or default families of delegate types.
In the black magic case (which all is in my head and I may well be insane), we are essentially saying:
take the lambda expression and the invocation of WithErrorHandling
and perform a syntactic transformation on the expression such that (o => ...).WithErrorHandling
is viewed, for this purpose, as DelegateExtensions.WithErrorHandling(o => ...)
and bind that.
Or, another way of looking at it, are their any types to which (o => ...)
is convertible having an extension method WithErrorHandling
taking a single argument of that type as their first parameter.
from csharplang.
I think that's a better idea because the compiler cannot know about all possible delegate types (unless dotnet/roslyn#3990 looks up for other delegate types in scope if Action and Func were not applicable which is unlikely).
from csharplang.
(o => ...).WithErrorHandling()
Related: dotnet/roslyn#3990
from csharplang.
@sharwell Oops; fixed
from csharplang.
@alrz yes dotnet/roslyn#3990 would benefit from this, but this proposal stands on its own.
from csharplang.
@aluanhaddad Yes, but that particular example that I mentioned requires the lambda to have a default type.
from csharplang.
@SLaks Thanks, edited.
from csharplang.
Yes; that's exactly what I mean.
It would make scanning for extension methods a bit more costly (since it has to consider more conversions); I don't know how bad that is.
from csharplang.
This would be beautiful, and would make the language more functional. The WithErrorHandling()
would be very appealing. The currying too.
Is it being considered for v8?
from csharplang.
@giggio It is not.
from csharplang.
Here is a use case for this, driven by #424
public static TResult Splat<T1, T2, T3, TResult>(this Func<T1, T2, T3, TResult> method, (T1, T2, T3) args)
{
return method(args.Item1, args.Item2, args.Item3);
}
void example()
{
var input = (1d, 1d, 1d);
(double, double) output;
// These both work:
output = Extensions.Splat(Globe.ConvertToSpherical, input);
output = ((Func<double, double, double, (double, double)>)Globe.ConvertToSpherical).Splat(input);
// This doesn't compile. Error:
// CS0119 'Globe.ConvertToSpherical(double, double, double)' is a method, which is not valid in the given context
output = Globe.ConvertToSpherical.Splat(input);
}
(double theta, double psi) ConvertToSpherical(double x, double y, double z)
{
throw new NotImplementedException();
}
from csharplang.
It would also be nice if we could do the following (automatically find the best matching type (action) for method groups):
value switch
{
value => value.SomeMethod,
}();
// or, if there is no native suport for this, we could at least define a method like this:
private Action AsAction(Action action)
=> action;
// and then do this:
value switch
{
value => value.SomeMethod.AsAction(),
}();
Because at the moment, if I have a task, I can use expression switches for "void like" meaning the void task returning nothing when awaited and have the await before the expression.
There's no reason for that limitation with void - just accepting void as a return type for an expression switch would be nice too, but I guess that's not realistic from what I've read in other issues.
Void-Task example that compiles (showing that in theory, void expressions would make just as much sense):
private Task Run(int value) => Task.CompletedTask;
private Task Run2() => Task.CompletedTask;
await (value switch
{
3 => Run(value),
_ => Run2(),
});
But this does not work:
private void Run(int value) => NoOperation();
private void Run2() => NoOperation();
// Doesn't work (statement not allowed there)
value switch
{
3 => Run(value),
_ => Run2(),
};
// Doesn't work (void can not be assigned to variable)
_ = value switch
{
3 => Run(value),
_ => Run2(),
};
// Doesn't work (no best type found)
value switch
{
3 => () => Run(value),
_ => Run2,
}();
// Does work, but is really annoying and adds noise for no reason, and you can't use expression bodies anymore if you're writing a method
Action runner = value switch
{
3 => () => Run(value),
_ => Run2,
};
runner();
Allowing Extension methods on Method groups would give some flexibility, and automatically detecting that Action is the best type here (not only when running Extension methods like the proposal) would be an even bigger improvement over status quo.
Are there any updates wheter this is considered as a champion for v11 or v12?
from csharplang.
Related Issues (20)
- [Proposal]: Collection Expressions Next (C#13 and beyond) HOT 47
- Open issues: Breaking changes HOT 29
- [Proposal]: Field and value as contextual keywords HOT 33
- [Proposal]: Extended identifier syntax
- [API Proposal]: IsNullableAttribute to flow nullability of generic type parameters into methods HOT 4
- Anonymous type optimization HOT 5
- Feature Request: Recursively Foreach
- [Proposal]: Relax `Add` requirement for collection expression conversions to types implementing `IEnumerable` HOT 2
- [Proposal]: Proposal for Allowing Single-Element Tuples in Type Definitions HOT 2
- [Proposal]: Params collections and older language versions HOT 1
- [Proposal]: Edit speclets to distinguish features already delivered from potential future enhancements HOT 3
- [Proposal]: `readonly` parameters in primary constructors for non-record types HOT 7
- [Issue]: Generic Type Specialization Not Working in C# HOT 38
- [Proposal]: AAAAAAAAAAAAAAAAAAAA
- Open questions for `field` and `value` as contextual keywords HOT 2
- Add collection literal support for `Memory<T>` and `ReadOnlyMemory<T>`. HOT 18
- Unexpected compiler behavior with records and implicit operators HOT 1
- YaoJunFeng
- Invalid implicit conversion from long to int HOT 6
- [Proposal]: Extending patterns to "as" HOT 19
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from csharplang.