Forum Discussion
Blazor parameter passed by reference
I got the impression that in Blazor parameters are always effectively passed by value which is why you need to use EventCallback for two-way binding to send a change in the parameter value back up to the component that passed it.
But not so; reference types really are passed by reference.
Therefore if a child component updates a parameter value that is a reference type then the value in the parent is changed and all you need to do is call `StateHasChanged` on the parent.
Is this as intended?
Have I misunderstood the documentation?
Example:
https://drive.google.com/file/d/1i1Rh36nHU1Z2voyHDtLVZ9GyziLw9AQq/view?usp=sharing
(Don't seem to be able to attach here and it's not really feasible to inline a whole Blazor project.)
2 Replies
- RichardB1640Copper Contributor
I don't use AI.
So you're claiming that reference values are indeed passed by reference, but you must not use this.
Does it follow that:
(1) when receiving a parameter of reference type you must take a deep copy of it upon which to make your changes,
(2) that this copy must be passed up via the event, and
(3) that the caller must deep copy the value received in the event back to the value that it passed? - shiracamusCopper Contributor
If you want a deeper breakdown of how C# handles memory for reference types versus how Blazor manages component state, try asking an AI. It's excellent at explaining these low-level C# concepts and how they interact with the Blazor lifecycle!
I got a response like this:
That’s an insightful observation! You’re touching on a key behavior of C# in Blazor.
To be technically precise, while you aren't using the ref keyword, passing a reference type (like a class) as a parameter still passes the "reference" by value. This means the child component receives a copy of the pointer to the same object in memory. When you modify a property of that object in the child, you are indeed modifying the same instance used by the parent.
However, relying on this for data updates is generally considered an anti-pattern in Blazor for several reasons:
- Unpredictable State: Blazor's change detection doesn't automatically "know" that an object's internal property was changed. This is why you found you needed to call StateHasChanged manually.
- One-Way Data Flow: The framework is designed for "Data down, events up." Modifying shared objects directly breaks this flow and can lead to bugs that are very hard to trace in larger apps.
- The "Blazor Way": Using EventCallback or @bind is the recommended approach because it tells the framework exactly when a change happened, allowing it to handle UI synchronization efficiently without manual intervention.