Skip to content
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

Make private fields readonly when possible #2103

Conversation

utpilla
Copy link
Contributor

@utpilla utpilla commented Jun 24, 2021

Changes

  • Make private fields readonly where possible
  • Rename static readonly field to start with a capital letter

@utpilla utpilla requested a review from a team June 24, 2021 02:00
@utpilla utpilla changed the title Make private fields readonly where possible Make private fields readonly when possible Jun 24, 2021
@codecov
Copy link

codecov bot commented Jun 24, 2021

Codecov Report

Merging #2103 (ea74b00) into main (79d4c49) will not change coverage.
The diff coverage is 100.00%.

Impacted file tree graph

@@           Coverage Diff           @@
##             main    #2103   +/-   ##
=======================================
  Coverage   79.65%   79.65%           
=======================================
  Files         233      233           
  Lines        7325     7325           
=======================================
  Hits         5835     5835           
  Misses       1490     1490           
Impacted Files Coverage Δ
src/OpenTelemetry/CompositeProcessor.cs 92.95% <ø> (ø)
...ourceInstrumentation/DiagnosticSourceSubscriber.cs 95.00% <ø> (ø)
...ter.ZPages/Implementation/ZPagesActivityTracker.cs 100.00% <100.00%> (ø)

@@ -30,8 +30,8 @@ namespace Examples.Console
internal class InstrumentationWithActivitySource : IDisposable
{
private const string RequestPath = "/api/request";
private SampleServer server = new SampleServer();
private SampleClient client = new SampleClient();
private readonly SampleServer server = new SampleServer();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curious, do we consider this as pedantic for example code?

@@ -24,7 +24,7 @@ namespace OpenTelemetry
{
public class CompositeProcessor<T> : BaseProcessor<T>
{
private DoublyLinkedListNode head;
private readonly DoublyLinkedListNode head;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want to get more perspectives regarding this one.
Making it readonly makes me feel that we're assuming the head should never change, and my worry is that other code might assume it (e.g. they might cache the value and assume it will never change).
While this is true for now, I guess in the future we might want to support something like PrependProcessor(processor) or InsertProcessor(index, processor).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@CodeBlanch do you know if the common practice in C# is to mark something readonly due to the semantics (e.g. we know that it will never change) or due to the actual usage (e.g. the fact that we didn't change it after initialization)?

To my knowledge in C++ it is focusing on semantics rather than the actual usage (e.g. const/mutable/volatile).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@reyang I would say in C# it is based on actual usage. There is an IDE analyzer built into VS that suggests/warns about this case if it can tell you aren't modifying a private field. So you would have to go out of your way/fight the tooling (suppression, disable rule) to stick with the semantic approach.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want to get more perspectives regarding this one.
Making it readonly makes me feel that we're assuming the head should never change, and my worry is that other code might assume it (e.g. they might cache the value and assume it will never change).
While this is true for now, I guess in the future we might want to support something like PrependProcessor(processor) or InsertProcessor(index, processor).

As of now, the processors get added in the order of the AddProcessor calls. Would we need to offer something like PrependProcessor or InsertProcessor if we can just ask the user to order their AddProcessor calls accordingly?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As of now, the processors get added in the order of the AddProcessor calls. Would we need to offer something like PrependProcessor or InsertProcessor if we can just ask the user to order their AddProcessor calls accordingly?

I think in the world where a single user/dev/team controls everything, this should work, and is not an issue from the beginning.

In the real world, there might be separation of roles/responsibilities. For example you have an infrastructure team which developed several security or privacy related processors, and that team wants to "prepend" the security/privacy processor before other processors introduced by feature teams. This can be solved by having the infrastructure team establishing some rules (e.g. all the teams should call AddInfrastructureProcessors before adding their stuff), but practically it might be challenging.

@CodeBlanch
Copy link
Member

@utpilla Another thing that might be worth doing: seal internal/private types.

@cijothomas cijothomas merged commit 86c524c into open-telemetry:main Sep 4, 2021
@utpilla utpilla deleted the utpilla/Makr-Private-Fields-ReadOnly-Where-Possible branch November 3, 2023 22:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants