-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Align WPF and WinForms code style guidelines #10017
Comments
I think I personally don't see any issues with those guidelines, assuming they are not enforced retrospectively in a breaking manner (e.g. turning public fields into properties). One point of discussion we had recently was the naming convention for pointer variables, I don't see those covered. Btw. why does it use backslashes for comments rather than forward slashes? |
Besides what miloush has pointed out, imho using collection expressions in cases like: or assigning e.g. private fields like:
should be discouraged. I'm also not a fan of primary constructors but I guess it's whatever. Otherwise I feel the guidelines are pretty well defined. |
@miloush No, we'll never make binary breaking changes. I'll call that out.
I'm going to call that out explicitly- I was just thinking about that again last night. I've tried a variety of options at scale, and I currently believe pointers should be named like any other variable, except in the case of pinning an existing variable. As pinning is usually constrained to a small block, I now use initials where the existing name is the best name: fixed (char* n = name)
{
}
// Not
fixed (char* namePtr = name)
// Avoid (can lead to much longer P/Invoke statements)
fixed (char* namePointer = name)
Whoops :) I'll fix that
@h3xds1nz while personally I don't see
I'm going to update this one to "consider for internal types only". API review will currently not approve any primary constructor APIs (as C# is free to add additional API and behavior in new versions). |
Looking through the WPF codebase for fixed blocks, I see 3 patterns: 1. Possibly the largest number is just prefix with
|
fixed (NativeMethods.MCHITTESTINFO_V6* pHitTestInfo = &hitTestInfo) |
fixed (float* pData = floatArray) |
2. Then there are just normal variables:
wpf/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Imaging/BitmapSource.cs
Line 684 in 5c87aff
fixed (void* pixelArray = &((byte[])pixels)[offset]) |
wpf/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/MarkupCompiler/PathInternal.cs
Lines 282 to 283 in 5c87aff
fixed (char* f = first) | |
fixed (char* s = second) |
3. And then there is a few p
prefixes with type indication:
wpf/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/StreamGeometry.cs
Line 91 in 5c87aff
fixed (byte *pbPathData = _data) |
Line 121 in 5c87aff
fixed (char* pchRes = achRes) |
I was gonna say I have never seen "Pointer" being added but then
Line 105 in 5c87aff
fixed (byte *bufferPointer = &buffer[offset]) |
Also this is a good one:
wpf/src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/TextFormatting/FormattedTextSymbols.cs
Lines 173 to 174 in 5c87aff
fixed (char* fixedCharArray = &charArray[0]) | |
fixed (int* fixedNominalAdvances = &nominalAdvances[0]) |
@h3xds1nz's preference seems to be ptr
prefix, while myself and @ThomasGoulet73 are used to p
prefix. The p
prefix might stand for pinned rather than pointer... The CLR via C# book uses p
prefix. C# specification looks like p
prefix to me, though more in pointer sense. Documentation for fixed statement is just chaos.
Either way, there is not that many instances of pointers in the repo and if the rules say "like normal variables", most of them would pass I guess.
@JeremyKuhne I know analyzers cannot enforce NOT using them in the cases I've mentioned, but it's definitely more readable to use the type IMHO and deserves to be mentioned if there's an agreement (I've mentioned it since you got multiple examples e.g. with succinct I know that unless you don't wanna define #9481 #9468 #10008 There's plenty of places I've managed to use As for the pointer case since @miloush brought it up; yeah I'm fan of |
Allowing C# to manage it they can improve behavior over time, much like they have for interpolated strings. I'm not precluding the option of pre-allocating the size- it is still completely legit to do
Moving to CsWin32 and ComWrappers in WPF will expose us to more pinning for sure. If you look at WinForms we have almost 500 Ideally C# would allow us to pin without needing another name as they're immutable anyway. Anything related to unsafe code isn't the highest priority for them though. :) // The dream :)
fixed (char* name);
PInvoke.SetName(&name); The biggest thing I don't want to see is devolving into using Hungarian notation as a broader thing. Perhaps a middle ground here of two options: fixed (Point* ls = lineStart)
{
}
// Or
fixed (Point* point = &points)
{
}
fixed (char* pName = name)
{
// Some larger block of code
}
// Not
fixed (char* namePtr = name)
fixed (char* c = name) |
I'd expect nothing less than improve of behavior over time but I cannot write it with my mind straight when I know what it is doing, haha. It's like cases where you'd e.g. want to put a ternary condition inside interpolated string e.g. (bool ? string literal : double) and you'll get a boxing append in the default interpolated string handler instead of separate generic and literal based on the condition.
Something like that would be the dream indeed.
Nah, I definitely didn't mean to lean into any other aspects of it, but I'll pick the prefix naming scheme for pointers happily.
Whether that's |
WPF and WinForms aren't far off. We both point to the runtime repo and Framework Design Guidelines, but WinForms has elaborated a bit more:
https://github.com/dotnet/winforms/blob/main/docs/coding-style.md
If we share the same guidelines, it will facilitate moving between the two repos for both internal and external contributors.
@Kuldeep-MS, @pchaurasia14
The text was updated successfully, but these errors were encountered: