Closed MadsTorgersen closed 7 years ago
Immutable types dotnet/csharplang#2543 would also be amazing.
I often wish for extension methods in nested private static classes, although "Allow extension methods in non-static classes" would cover most of that need.
If I had to pick a single feature that excites me most, it would without doubt be Algebraic data types. Very happy to see it on the Strong interest list!
@JayBazuzi we only wanted them in nested private classes because of the arbitrary requirement that they couldn't be in a nonstatic class
What about a common sense and reasonably easy to implement feature to retrieve a key from a Dictionary, HashSet, SortedDictionary, or any other container class that uses keys?
Right now, only values can be retrieved from a Dictionary - not the key. Unless iterating through the dictionary with a foreach loop - which would be prohibitively expensive when doing a simple look up. It would be nice if a method could be provided that would return the key/value pair for a given key from a matching "key". The reason why it would be useful is because the Equals method does not necessarily mean that 2 objects are exactly equal - since the Equals method can and often does only use a subset of the fields of a class to make that determination. I have come across cases where it would have been quite helpful to access the stored key in the dictionary when my code found the item in the dictionary. There were other fields in the stored key that I needed to access that were not present in the key used to access the dictionary, so I had to use the suggested work around given in the link above.
@RobertGBryan, it's a simple thing to include the key with the value or to make the value a tuple. If there's a canonical name, it should be probably included with the value.
@wesnerm, Sounds like you are suggesting using the work around specified in the link above. The drawback as pointed out by the original poster in that link is that it adds complexity as well as needlessly takes up more memory. How hard would it be to provide a method to return the key and value? Wouldn't this be a fairly simple task to implement?
@HaloFour,
"Adding a new "default method" would still leave a blank spot in the vtable slot that older runtimes would not know to wire up to that static instance method. You could have newly compiled classes do that automagickally but not already compiled assemblies."
No, there would be no blank slot. It's not a runtime feature, but a compiler feature.
In the IL, there would always be some method assigned to slot. In C# 7.0, the compiler would implement a private instance method that calls the static interface method. (Calls to static interface methods are actually supported by older versions of C#.)
.method private virtual void ClassInterfaceMethod()
{
.override IInterface::InterfaceMethod
ldarg.0
call void IInterface::InterfaceStaticMethod(Interface)
ret
}
InterfaceStaticMethod and InterfaceMethod might have the same name, since that is possible in IL.
An older compiler using a library with a default interface method would not know about it and would require the developer to always implement either a explicit or implicit interface implementation. A developer using the older compiler could recreate the same implementation as C# 7.0 manually.
void IInterface.ClassInterfaceMethod()
{
IInterface.InterfaceStaticMethod(this);
}
Default implementations can be implemented with attributes on the static interface method, just like with extension methods or param arrays. C# 7.0 would recognize the default implementations automatically when a user-provided implementation is missing. With no performance loss, C# 7.0 would locate a static method of the same name taking the same arguments (including the this parameter) and checking for the presence of a DefaultInterfaceMethodAttribute on the static method.
@RobertGBryan You should suggest that to the CoreFX Team. They consider possible API changes to the framework.
@RobertGBryan, that's a library issue, not a language issue. That won't be fixed by a new feature in the language.
@wesnerm That would break all existing implementers of that interface that are compiled outside of that project. That defeats most of the purpose of "default methods" which is the ability to add new trivial methods to an existing interface without requiring recompilation of implementing classes.
If you are going to implement Null safety in the Kotlin way, maybe you could check out a few of their other concepts too. I think especially the concepts of smart casts and delegated properties could be really useful...
String templates, first-class delegation, extension properties and
singleton objects are also nice.
BTW: I think delegated properties (maybe in combination with first-class delegation?) could also solve the INPC problem.
Why not Metaprogramming? :'(
+1 Type providers! Please!
@MadsTorgersen can u elaborate on "compile time attributes"?
Enum and generic constraints please so i can delete this project https://github.com/Fody/ExtraConstraints
Not sure how this fits in but would like to see Enums made more useful. Something like java Enums. I cannot say how many times I would like to have a bit more information attached to the Enum (e.g. a description). Can be done with [Description] attribute today but just would be nice if Enums were more extensible. The other thing would be the capability to do more generic work with Enums. Hope this makes some sense.
What happened to duck-/structural typing? I seem to recall it was mentioned in one of the design note issues... That would be really awesome. Or even a hack like Assembly Neutral Interfaces :smile:
+1 for structural typing. That would be awesome. Spoilt by TypeScript.
Excuse my ignorance, but what is INPC?
INotifyPropertyChanged - I guess it's talking about an automatic implementation a la ES6 Object.Observe
I personally would love this (especially recursive INPC) for doing object diffing of viewmodels and change tracking for reactive server side views and stuff.
@mcintyre321 thanks. Never used it :stuck_out_tongue:
I don't think #154 would require CLR support, but if it does I'd be interested how. When I designed it, I envisioned it as a compile-time language-only feature.
I can see how dotnet/roslyn#129 would require run-time support.
@khellang I think #154 could be considered Duck typing.
@RobertGBryan in case you weren't aware, IDictionary
, IDictionary<TKey,TValue>
, HashTable
, Dictionary<TKey,TValue>
etc. all implement IEnumerable
. Specifically, Dictionary<TKey,TValue>
implements IEnumerable<KeyValuePair<TKey,TValue>>
which I think is what you're looking for. It also has Keys
and Values
properties that you can use to iterate them separately, if desired.
+1 for Nullability tracking (Proposal: dotnet/roslyn#227)
+1 for ref locals. When you have a very hot number-crunching loop, you have to resort to an array of structs to hold your data to improve data locality, and to shave off the final milliseconds you need to avoid copying the element you are processing into a local. This either means recalculating the offset again and again or extracting the loop body into a static method with a ref parameter. The latter option is the fastest, but can be confusing to those supporting the code.
Can I please add a new feature request, if this isn't the place to do so please tell me where the right place is.
Not sure what to call it, but basically I want the ability to pass a reference into a method and know that method will not take an additional reference. For example, if I allocate a large block of memory and I pass a reference to that allocation into a method, I would like to know that the method will not keep a reference to the memory thus preventing the GC from doing its job.
Effectively I'd like parameter operator which creates a contract with the call that the method will not take a reference to the parameter nor will it is pass the reference to another method which doesn't support the same contract.
A use-case could be something as simple as Encoder
's .GetString
method.
public string GetString(&byte[] bytes)
Where the &
is used to signify that the reference cannot be held on to.
@whoisj
Can I please add a new feature request, if this isn't the place to do so please tell me where the right place is.
You can create a new issue for the proposal. Then it will be tracked separately and can have its own dialog.
@HaloFour yay, thanks!
Any news about the constraints support for delegates and enums? Here is a link to bring some memories back: http://blogs.msmvps.com/jonskeet/2009/09/10/generic-constraints-for-enums-and-delegates/
@ehouarn-perret Additional constraints are explicitly mentioned in the opening post itself: "Small but useful" and "Interesting but require CLR support" sections.
To note, as mentioned on Jon Skeet's blog and on here and CodePlex numerous times, supporting delegates or enums as generic type constraints are both currently supported by the CLR, just not by C#. C# already recognizes and enforces said constraints if you reference another assembly that uses them.
Here are the two existing proposals for this:
dotnet/roslyn#158 Proposal: Support System.Delegate as a generic constraint dotnet/roslyn#262 Proposal: support an enum constraint on generic type parameters
@HaloFour @dsaf Alright then, glad to know that those suggestions are still around and have been considered for C# 7 :-)
I'm already aware of what Jon Skeet has found (a long time ago, about 6-7 years ago). And fully agreed as it has been already pointed out many times this is already supported by the CLR. Sadly, C# still lacks its language counterpart.
Thanks about the links, that was exactly what I was looking for.
Shouldn't dotnet/roslyn#1384 (Family AND Assembly access modifier) be on this list, given that it was going to be included in C# 6 but didn't quite make it? As a minor enhancement that doesn't require CLR changes, it probably belongs in the Small but useful bucket.
@badja It's not bucketed because Mads is probably still having nightmares after the wars on CodePlex over what word to call the operator.
@MgSam commented on Jul 1, 2015, 3:17 PM GMT+2:
@badja It's not bucketed because Mads is probably still having nightmares after the wars on CodePlex over what word to call the operator.
IMO it's better to have this feature even if the chosen keyword isn't perfect, than not have it just because the team and the community couldn't agree on a keyword.
IMO it's better to have this feature even if the chosen keyword isn't perfect, than not have it just because the team and the community couldn't agree on a keyword.
Just learn from C++/Cli folks and move on.
Just learn from C++/Cli folks and move on.
That was the initial plan... C++/CLI uses protected private
. C# 6 was initially supposed to use private protected
, but everyone hated it. That's what caused the fruitless debate to pick a different keyword.
@thomaslevesque
Can't please everyone. On the Internet it's more like "can't please anyone." I think they should just go with the same keywords as C++/CLI* and implement it. It's a minor win and being consistent should reduce potential confusion, although the use-cases are so limited it probably won't come up much anyway.
* Yes, I am aware that private protected
and protected private
are the same thing given that the modifier keywords are permitted to be in any order.
protectedandinternal
and protectedorinternal
is a nearly perfect choice. I can't understand why English speakers so care about the 'purity'.
Yes, protectedandinternal
and protectedorinternal
are very ugly, but they are very very CLEAR.
There will be 7 access modifiers:
public
protected
internal
private
protectedandinternal
protectedorinternal
protected internal
/ internal protected
(for backward compatibility)@knat Doesn't fit with how access modifiers are already specified in C#.
If C# doesn't just copy C++/CLI and implement with the original plan it's best to just leave the feature out because the "keyword wars" that ensued are the epitome of a waste of time.
@HaloFour I think the Roslyn team is capable of and should really make firm decisions like this. Whatever it's called as long as it's done.
I edited the list to reflect decisions from dotnet/roslyn#3912 and dotnet/roslyn#3910.
method references as implemented in java are very neat and prevent a lot of unnecessary lambda expressions.
method references as implemented in java are very neat and prevent a lot of unnecessary lambda expressions.
You mean doing something like that items.Where(IsValid)
instead of items.Where(i => IsValid(i))
? It's already possible in C# (actually it was possible before lambda expressions even existed in C#).
A nice thing that Java 8 does and C# doesn't, though, is allow constructors to be used as method references, e.g. items.Select(SomeClass::new)
. I'd like to see that in C#, but I suspect it would require some changes at the CLR level too, because currently you can't create a delegate directly from a constructor.
@thomaslevesque yes it's already possible but not from the outside of the class. something like this customers.Select(Customer::Name)
. However, you can create delegates from instance members via Delegate.CreateDelegate
.
@thomaslevesque yes it's already possible but not from the outside of the class
The fact that the method is in another class is irrelevant, as long as it's public. My example above would work just as well if IsValid
is in another class:
items.Where(Utils.IsValid)
items.Where(validator.IsValid)
something like this
customers.Select(Customer::Name)
Well, in this case it's a bit different, because Name
is a property, not a method (I assume). I think the point you're trying to make is that we can't reference an instance method this way if we don't have an instance? It's not something that I miss personally, but I see how it could be useful.
it's a bit different, because
Name
is a property, not a method (I assume).
I'm relying on the fact that properties are internally implemented as methods, e.g. get_Name
in this case.
I'm relying on the fact that properties are internally implemented as methods, e.g.
get_Name
in this case.
Yes, but there are two methods (for read-write properties): get_Name
and set_Name
. Which one would Customer::Name
refer to? I'm not against such a feature, but it would have to be carefully thought through.
(revision circa April 26 2016, clarifying edit June 14, 2016)
This is a list of features are looking at for C# 7, roughly categorized according to our current level of interest and estimated plausibility.
Please don't infer anything about the final shape of C# 7 (or future versions). The list is a tracking mechanism for work, not a description of the outcome. We have a long way to go yet!
Each bucket is in no particular order. I'll try to think of a more systematic way of cross-referencing with proposals and notes, but wanted to get the list out there.
I'll keep the list updated as we look at more feature ideas and change our minds about the relative importance.
Strong interest
Some interest
Non-language
See also Language Feature Status (compiler team)