You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This issue is for teams to highlight work for the community that will release in .NET 8 Preview 2
To add content, use a new conversation entry. The entry should include the team name and feature title as the first line shown in the template below.
Required
## Team Name: Feature title
[link to the tracking issue or epic item for the work]
Tell the story of the feature and anything the community should pay particular attention
to be successful in using the feature.
Optional
Below are three additional items to consider. These will help the .NET 8 blog team and the community throughout the release.
Link to documentation.
Where can we send people to learn more about the feature?
Link to where you'd like people to provide feedback for this feature.
Where can people best comment on the direction of this feature?
Whether you would like assistance from the .NET 8 writers to craft a story for this feature.
System.Reflection: introspection support for function pointers
This feature adds the capability to obtain function pointer metadata including parameter types, the return type and the calling conventions. Previously, the IntPtr type was used for a function pointer type such as with typeof(delegate*<void>()) or when obtaining a function pointer type through reflection such as with FieldInfo.FieldType.
A function pointer instance, which is a physical address to a function, continues to be represented as an IntPtr; only the reflection type was changed with this feature.
This new functionality is currently implemented in the CoreCLR runtime and in MetadataLoadContext. Support for the Mono and NativeAOT runtimes are expected later.
FieldInfofieldInfo=typeof(MyClass).GetField(nameof(MyClass._fp));// Obtain the function pointer type from a field. This used to be the 'IntPtr' type, now it's 'Type':TypefpType=fieldInfo.FieldType;// New methods to determine if a type is a function pointer:Console.WriteLine(fpType.IsFunctionPointer);// TrueConsole.WriteLine(fpType.IsUnmanagedFunctionPointer);// True// New methods to obtain the return and parameter types:Console.WriteLine($"Return type: {fpType.GetFunctionPointerReturnType()}");// System.Voidforeach(TypeparameterTypeinfpType.GetFunctionPointerParameterTypes()){Console.WriteLine($"Parameter type: {parameterType}");// System.Int32&}// Access to custom modifiers and calling conventions requires a "modified type":TypemodifiedType=fieldInfo.GetModifiedFieldType();// A modified type forwards most members to its underlying type which can be obtained with Type.UnderlyingSystemType:TypenormalType=modifiedType.UnderlyingSystemType;// New methods to obtain the calling conventions:foreach(TypecallConvinmodifiedType.GetFunctionPointerCallingConventions()){Console.WriteLine($"Calling convention: {callConv}");// System.Runtime.CompilerServices.CallConvSuppressGCTransition// System.Runtime.CompilerServices.CallConvCdecl}// New methods to obtain the custom modifiers:foreach(TypemodreqinmodifiedType.GetFunctionPointerParameterTypes()[0].GetRequiredCustomModifiers()){Console.WriteLine($"Required modifier for first parameter: {modreq }");// System.Runtime.InteropServices.InAttribute}// Sample class that contains a function pointer field:publicunsafeclassMyClass{publicdelegate* unmanaged[Cdecl,SuppressGCTransition]<inint,void>_fp;}
Parameterized types including generics, pointers, and arrays such as an array of function pointers (e.g. delegate*<void>[]) are supported. Thus, the Type.ElementType property and the Type.GetGenericArguments() method can be used to obtain further types which ultimately may be a function pointer. In addition, a function pointer parameter type is allowed to be another function pointer type.
Reacted by Max Katz, Rich Lander, Jiachen Jiang, Ralf and GrayAlex715
FYI: I think this feature description from @steveharter is a best-practice example: #8134 (comment). It describes the user-facing problem to solve, provides additional contexts (and links) and then ends with a great example.
If you are not sure how to write this, Steve's example is a good one.
@JeremyLikness, @JonDouglas, et al -- For the DataAnnotations APIs that @eiriktsarpalis called out, it's probably good to note in the blog/release notes/docs that these were inspired by validation scenarios beyond the typical UI data entry validation scenarios that most DataAnnotations validators are geared towards. We've been learning from Options validation scenarios used in cloud-native services, and these new validation attributes are primarily targeting those scenarios. Base64StringAttribute is a clear example of a piece of data that would come from configuration or another system, and not from user's data entry.
For these cloud-native scenarios, we are expecting to do more work in the DataAnnotations space through the release.
Reacted by Ssewannonda Keith Edwin, well.james and Adipa Wijayathilaka
What is the reason behind to name the counterpart of "AllowedValues" attribute "DeniedValues" instead of "DisallowedValues"? Because it is shorter? DisallowedValues would be the more intuitive candidate to think of (at least for me)
This accepts any values in the open
interval but rejects the boundary values 0 and 1 themselves.
Included and Excluded would be clearer terms. "Exclusive" is more commonly used to mean "excludes all others", like "exclusive content" that a media company might generate, or an "exclusive story" that a journalist may write about. In this attribute you intend to mean something like the opposite of that.
The current naming is also a double negative sometimes. These both should have been Is*BoundIncluded
@eiriktsarpalis - Im not going to be able to use this attribute correctly as it currently is without always having to check the docs, and I'm not the only one. I probably won't even bother to check the docs and will just avoid using it because I know these names could be problematic for someone else later.
I agree with the two comments above. *Included makes more sense than *Exclusive as its meaning is less open for interpretations.
Because it is in preview, the naming still could be changed. (But will it be changed?)
@demming - maybe they are standard terms if you went to college or at least had some formal education with computer science or enough mathematics. And you know English well enough to know that the "bounds" you are referring to are not the ones from the expression "leaps and bounds", but are referring to a shortened version of the word "boundaries".
English is an overly complicated language with lots of odd and inconsistent rules. "IsUpperBoundExclusive" has too many interpretations that could lead to the code being wrong.
@leecow, package System.ComponentModel.Annotations is marked as deprecated and not maintained in NuGet as of now. But I see there is work on progress on that library going on. Will it be another package?
@alexaronov The changes are .NET 8 only, we have no plans on releasing a NuGet package update. Because the changes modify APIs of types that are already present in the shared frameworks of earlier versions of .NET, it would be challenging to make these available in a package for older targets.
@eiriktsarpalis - I see the names of these have changed to MinimumIsExclusive and MaximumIsExclusive and these solve part of the problem with the naming, but they leave the part that will create the most bugs and that is the word "Exclusive". This is the bigger of the two problematic parts because of how it conflicts with idiomatic use of the word. I am aware that c# is not English but our programs that do use English words should be borrowing ones with unambiguous meanings.
In addition to that, both the new and the older names qualify as a negative name, which does not follow long standing convention for booleans. The new names actually go farther away from those conventions than the previous choices due to the placement of the "be" word.
IsMinimumIncluded and IsMaximumIncluded would be properly aligned with those conventions (and may even be shortened to IsMaxIncluded and IsMinIncluded and still be permissible) and would be much clearer for the entire user base.
I have no idea what MinimumIsExclusive/MaximumIsExclusive means. It is highly counter intuitive to me.
I also agree with @StingyJack's comments, but I would prefer MinimumIsIncluded instead of IsMinimumIncluded , which may not align perfectly with naming convention but is the most understandable naming to me (and probably to many more people)
Thanks for the insight on moving Is.
I still think that the properties should be renamed to Inclusive so as to not have a double negative Exclusive = False is confusing. Inclusive = True not so much.
Activity
steveharter commentedon Feb 24, 2023
System.Reflection: introspection support for function pointers
This feature adds the capability to obtain function pointer metadata including parameter types, the return type and the calling conventions. Previously, the
IntPtrtype was used for a function pointer type such as withtypeof(delegate*<void>())or when obtaining a function pointer type through reflection such as withFieldInfo.FieldType.A function pointer instance, which is a physical address to a function, continues to be represented as an
IntPtr; only the reflection type was changed with this feature.This new functionality is currently implemented in the CoreCLR runtime and in
MetadataLoadContext. Support for the Mono and NativeAOT runtimes are expected later.For more information, see the API issue and Design.
An example using reflection:
Parameterized types including generics, pointers, and arrays such as an array of function pointers (e.g.
delegate*<void>[]) are supported. Thus, theType.ElementTypeproperty and theType.GetGenericArguments()method can be used to obtain further types which ultimately may be a function pointer. In addition, a function pointer parameter type is allowed to be another function pointer type.richlander commentedon Mar 6, 2023
FYI: I think this feature description from @steveharter is a best-practice example: #8134 (comment). It describes the user-facing problem to solve, provides additional contexts (and links) and then ends with a great example.
If you are not sure how to write this, Steve's example is a good one.
eiriktsarpalis commentedon Mar 7, 2023
System.ComponentModel.DataAnnotations Extensions dotnet/runtime#82311
We're introducing extensions to the built-in validation attributes in System.ComponentModel.DataAnnotations:
RequiredAttribute.DisallowAllDefaultValuesThe
RequiredAttributenow allows validating that structs do not equal their default values. For example:will fail validation if its value equals
Guid.Empty.RangeAttributeexclusive boundsUsers can now specify exclusive bounds in their range validation:
This accepts any values in the open$(0, 1)$ interval but rejects the boundary values 0 and 1 themselves.
LengthAttributeThe
LengthAttributecan now be used to set both lower and upper bounds for strings or collections:AllowedValuesAttributeandDeniedValuesAttributeThese attributes can be used to specify allow lists and deny lists for validating a property:
Base64StringAttributeAs the name suggests, this attribute validates that a given string is a valid Base64 representation.
jeffhandley commentedon Mar 8, 2023
@JeremyLikness, @JonDouglas, et al -- For the DataAnnotations APIs that @eiriktsarpalis called out, it's probably good to note in the blog/release notes/docs that these were inspired by validation scenarios beyond the typical UI data entry validation scenarios that most DataAnnotations validators are geared towards. We've been learning from Options validation scenarios used in cloud-native services, and these new validation attributes are primarily targeting those scenarios.
Base64StringAttributeis a clear example of a piece of data that would come from configuration or another system, and not from user's data entry.For these cloud-native scenarios, we are expecting to do more work in the DataAnnotations space through the release.
CleanCodeX commentedon Mar 14, 2023
What is the reason behind to name the counterpart of "AllowedValues" attribute "DeniedValues" instead of "DisallowedValues"? Because it is shorter? DisallowedValues would be the more intuitive candidate to think of (at least for me)
eiriktsarpalis commentedon Mar 14, 2023
@CleanCodeX naming follows from allowlists and denylists.
JonDouglas commentedon Mar 24, 2023
Released: https://devblogs.microsoft.com/dotnet/announcing-dotnet-8-preview-2/
StingyJack commentedon Mar 25, 2023
Included and Excluded would be clearer terms. "Exclusive" is more commonly used to mean "excludes all others", like "exclusive content" that a media company might generate, or an "exclusive story" that a journalist may write about. In this attribute you intend to mean something like the opposite of that.
The current naming is also a double negative sometimes. These both should have been
Is*BoundIncluded@eiriktsarpalis - Im not going to be able to use this attribute correctly as it currently is without always having to check the docs, and I'm not the only one. I probably won't even bother to check the docs and will just avoid using it because I know these names could be problematic for someone else later.
TonyValenti commentedon Mar 25, 2023
@StingyJack - I felt the same way about this but didn't say anything because I felt like I might not be in the majority, but I agree with you 100%.
I would even suggest taking it a step further:
Includes*BoundCleanCodeX commentedon Mar 25, 2023
I agree with the two comments above. *Included makes more sense than *Exclusive as its meaning is less open for interpretations.
Because it is in preview, the naming still could be changed. (But will it be changed?)
demming commentedon Apr 16, 2023
In the context of bounds, inclusive and exclusive bounds are standard terms though.
StingyJack commentedon Apr 18, 2023
@demming - maybe they are standard terms if you went to college or at least had some formal education with computer science or enough mathematics. And you know English well enough to know that the "bounds" you are referring to are not the ones from the expression "leaps and bounds", but are referring to a shortened version of the word "boundaries".
English is an overly complicated language with lots of odd and inconsistent rules. "IsUpperBoundExclusive" has too many interpretations that could lead to the code being wrong.
[-]What's new in .NET 8 Preview 2 [WIP][/-][+]What's new in .NET 8 Preview 2[/+]alexaronov commentedon May 6, 2023
@leecow, package System.ComponentModel.Annotations is marked as deprecated and not maintained in NuGet as of now. But I see there is work on progress on that library going on. Will it be another package?
eiriktsarpalis commentedon May 6, 2023
@alexaronov The changes are .NET 8 only, we have no plans on releasing a NuGet package update. Because the changes modify APIs of types that are already present in the shared frameworks of earlier versions of .NET, it would be challenging to make these available in a package for older targets.
StingyJack commentedon May 7, 2023
@eiriktsarpalis - I see the names of these have changed to
MinimumIsExclusiveandMaximumIsExclusiveand these solve part of the problem with the naming, but they leave the part that will create the most bugs and that is the word "Exclusive". This is the bigger of the two problematic parts because of how it conflicts with idiomatic use of the word. I am aware that c# is not English but our programs that do use English words should be borrowing ones with unambiguous meanings.In addition to that, both the new and the older names qualify as a negative name, which does not follow long standing convention for booleans. The new names actually go farther away from those conventions than the previous choices due to the placement of the "be" word.
IsMinimumIncludedandIsMaximumIncludedwould be properly aligned with those conventions (and may even be shortened toIsMaxIncludedandIsMinIncludedand still be permissible) and would be much clearer for the entire user base.TonyValenti commentedon May 7, 2023
I definitely agree with @StingyJack 's comments.
CleanCodeX commentedon May 7, 2023
I have no idea what MinimumIsExclusive/MaximumIsExclusive means. It is highly counter intuitive to me.
I also agree with @StingyJack's comments, but I would prefer MinimumIsIncluded instead of IsMinimumIncluded , which may not align perfectly with naming convention but is the most understandable naming to me (and probably to many more people)
eiriktsarpalis commentedon May 8, 2023
The naming was changed intentionally, rationale can be found here, I would recommend making a case in that issue.
TonyValenti commentedon May 8, 2023
Thanks for the insight on moving
Is.I still think that the properties should be renamed to Inclusive so as to not have a double negative
Exclusive = Falseis confusing.Inclusive = Truenot so much.