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
Champion "Extension function members" #192
Comments
|
Almost agree and totally support with a bit of arguments and concerns
/// static class cannot extend anything before so it not breaking any previous code
public static class Ext : MyStruct
{
} |
|
I think I'm late to the party and forgive my ignorance, but what about just supporting |
|
@Bartmax |
|
i know that, but that doesn't mean it can be "reworked" to allow classes from other assemblies hence creating extensions for arbitrary classes. |
|
I'd suggest the following syntax for extension declarations, internal extension [class] StringExtensions for String { }
internal extension [class] GenericExtensions<T> for T where T : class { }I believe the name should be optional for convenience (e.g. private nested extension declarations don't really need to be named): private extension [for] String { }
private extension<T> [for] T where T : class { }Similarly, instead of base list, we could use implement TraitT for String { }
implement<T> FooT for T where T : BarT { }This has various advantages like segregating impls so that they do not show up on all instances. Explicit implementations could have the same effect in extension declarations, but I think it's good to separate these concerns (auxiliary methods vs trait implementations). |
|
Please consider this feature for the nearest releases. It would make life so much easier. |
|
I think it would be good to have the ability to write extensions for multiple classes in a single context. For example, if you need to cache reflection objects (especially when you're emitting something), sharing said cache would probably be a good idea, and creating an additional static class for that sole purpose would feel somewhat awkward. Also, I think many would benefit from extensions existing in a non-global context (consider |
|
@Bartmax, there is no such thing as partial classes. There are partial class definitions and it's a source code feature not an assembly feature (@orthoxerox). |
|
Well, it's 100% in the |
|
@Joe4evr That milestone has a release date of January 1 2100 - I think most of us would like to see this feature in a version of C# that's released before we're all dead... |
|
@paulomorgado and @orthoxerox, I'm sure @Bartmax is not suggesting using partial class definitions. He's suggesting using a similar syntax to theirs, but for extension members. It's a great idea: |
|
@JVimes I totally agree with your proposed syntax so not to introduce anymore new keyword like the example with the for keyword. But what about the cases you are implementing extension methods for types that implement a certain interfaces? Event the naming would be misleading. Like we are doing and extension class for IEnumerable and you have to do something like the following: public extension class IEnumerable<T>
{
// Extension members of all types go here
// Don't need to pollute parameter lists with "this ClassName foo"
}Which breaks the naming conventions for C#. Based on your approach i would go with a syntax like this public extension class ExtensionName : ClassName
{
// Extension members of all types go here
// Don't need to pollute parameter lists with "this ClassName foo"
}So it should support the same syntax as class inheritance, generics, etc. The only thing with this approach is that it may be misleading to that user, thinking he should implement the interface or abstract class (as it looks like you are extending/implementing some type. |
|
So, would this proposal cover being able to add events as an extension to an existing class as well? |
|
dotnet/roslyn#11159 (comment):
|
|
I assume this would support interfaces. This would be really neat, since you could make a mixin like this (with the syntax specified by ivi-hamiti): interface IMyMixin {}
public extension class MyMixinImpl : IMyMixin {
// mixin stuff here
} |
|
@ddobrev This is no release that this feature is scheduled for. |
|
@ddobrev Your comment isn't helpful or constructive. Please try to stay on topic. I understand you very much want this feature. However, this is one of thousands of features that people would like and we're prioritizing based on lots of pieces of data to determine which ones we should ship. Importantly, many features we do are not at all sugar (though many are as well). Much of the last few releases has been driving work that is enormously important for scalability and performance (especially for games, server environments, and mobile devices). Hopefully in the future you'll find our picks are more what you want. But that won't always be the case. Have a good day :) |
|
Any definition doc to read for this proposal? It mentions "Extension Everything" under the roslyn repo. But that's
What are "Extension function members"? Is there a post missing or is missing a log from an older issue? |
|
Personally, I discourage field extensions. This is against the philosophy of adding a helper to the class. If you need to store data, that's not a helper - that data structure. And data structure should be implemented by inheritance, probably. Also that will face many technical challenges, which will cause either poor performance or introducing changes in the CLR (or both) because the only ways (do you have others?) to implement this feature is a) implement a dictionary for the field (performing poorly) or b) somehow extends the CLR so objects can have additional fields. But properties (and indexers, etc.) are welcome. Interfaces are also good (i.e. implementing interface through extensions) since interfaces indicates an ability of the type. For instance, be serialized, format itself, etc.. |
|
@CyrusNajmabadi Is Mads no longer working? |
|
Hard to determine the current proposal syntax from this thread and I'm not certain where to find it elsewhere. I've seen some mentions of proposals where they keyword static isn't present. I'm fairly uneducated on the backend of how this all works but currently it looks like the IL extension methods are static, if this would go unchanged the |
|
The use of
|
|
I'm not sure if it'd be part of this proposal or a new feature request. But I just encountered a scenario where I wanted to have an extension that was using a It'd be great to be able to flag this type of scenario so the compiler would let me access the protected sub-class methods as long as I'm only using the extension method from a place where I'd have access to those compared to just anywhere. E.g. In XAML, when extending and writing a custom Control, we inherit from the We do this as a private method currently, but it is a general function applicable to anyone inheriting from |
|
I just encountered a scenario where I'm using an API and I'm unable to modify the base class but must use its derived classes (because of added logic existing only in the different derived classes). I looked into extension methods and it almost gave me what I wanted but I still needed to add custom properties... Then I looked into adding an interface, and again, it almost did what I needed it to do but interfaces can't tell what class/type it'll be using and therefore can't access said class's public members which the method I was writing again needed. The method I'd like to use has the exact same implementation on all derived classes, but now I am forced to re-implement it anyways, and it's just not as clean, not to mention time consuming. Add in the benefit that having the possibility to use class extensions you could write everything you need for your personal use case once, have it work for you, then easily create a pull request with all the same code (or close) and let the maintainer decide whether to merge or not in the main repo. In any case your version still works fine for you and it might even get merged and contribute to the ecosystem at large. It's a win-win, two birds one stone. |
|
Allowing extension methods for implicit casts would be very helpful to simplify using the new JsonNode APIs in .NET 6: dotnet/runtime#53195 (comment) I don't believe that implicit casts will ever be added to the actual JsonObject classes. But if we could define them in an extension method in a sub-namespace, users could easily opt-in to implicit conversions by including the sub-namespace. |
|
I wanted to add one simple to understand scenario in higher level code where this would have been a great feature to have on the library level. We wanted to support SQL row value syntax in Entity Framework Core (dotnet/efcore#26822). Currently, this is the most readable C# syntax the user will have to write to represent row value: .Where(b => EF.Functions.GreaterThan(new[] { b.Column1, b.Column2 }, new[] { 1, 2 }))Not so readable. This proposal would in theory allow providing custom tuple operators and allow the user to write the following instead: .Where(b => (b.Column1, b.Column2) > (1, 2)) |
|
Extension properties would greatly help in dotnet/comet, which heavily uses builder pattern to create views. new ShapeView(new Circle()
.Fill(LinearGradient)
.Style(DrawingStyle.Fill)).Frame(200,100),With extensions new ShapeView(new Circle { Fill = LinearGradient, Style = DrawingStyle.Fill }) { Frame = (200, 100) },
// Frame have signature: void set_Frame(this ShapeView view, (double, double) size)new Text("TEST PADDING").Frame(height:30).Margin(top:100),With extensions new Text("TEST PADDING") { FrameHeight = 30, MarginTop = 100, },I find extension property version more readable, especially in first case |
|
Extension static methods would be useful for classes in testing/mocking frameworks and elsewhere that define fluent methods hanging off a static class like |
|
@uecasm was just coming to call out the same thing. Being able to write extensions off of |
|
Is there anywhere to see if any progress is being made on this issue? |
|
Yup. Right here. |
|
Doesn't #5497 supersede this? |
|
That one's a non-starter for me because it requires an extra keyword/decoration on the class being extended. The whole point of extension methods is to extend things that the original designer didn't think of and didn't make extensible any other way. |
@uecasm Do you mean #5497? I think it does not… From the proposal public class DataObject
{
public DataObject this[string member] { get; set; }
public string AsString() { }
public IEnumerable<DataObject> AsEnumerable();
public int ID { get; }
}gets extended by public extension JsonDataObject : DataObject
{
public string ToJson() { … this … }
public static DataObject FromJson(string json) { … }
}I don't see any special keyword. I havn't read the howl thread, so maybe I skiped something |
|
Oh, maybe I overlooked something then. It looked to me like you could only extend |
|
No, as I understood, Roles are a construct to add Interfaces to external types (and maybe more), but are not nessesary to extend something. |
|
Omg, no ETA for this best feature for C#? 😞 |

See also dotnet/roslyn#11159
The text was updated successfully, but these errors were encountered: