92 lines
1.7 KiB
Plaintext
92 lines
1.7 KiB
Plaintext
While the properties of a ``++readonly++`` reference type field can still be changed after initialization, those of a ``++readonly++`` value field, such as a ``++struct++``, cannot.
|
|
|
|
|
|
If the member could be either a ``++class++`` or a ``++struct++`` then assignment to its properties could be unreliable, working sometimes but not others.
|
|
|
|
|
|
== Noncompliant Code Example
|
|
|
|
----
|
|
interface IPoint
|
|
{
|
|
int X { get; set; }
|
|
int Y { get; set; }
|
|
}
|
|
|
|
class PointManager<T> where T: IPoint
|
|
{
|
|
readonly T point; // this could be a struct
|
|
public PointManager(T point)
|
|
{
|
|
this.point = point;
|
|
}
|
|
|
|
public void MovePointVertically(int newX)
|
|
{
|
|
point.X = newX; //Noncompliant; if point is a struct, then nothing happened
|
|
Console.WriteLine(point.X);
|
|
}
|
|
}
|
|
----
|
|
|
|
|
|
== Compliant Solution
|
|
|
|
----
|
|
interface IPoint
|
|
{
|
|
int X { get; set; }
|
|
int Y { get; set; }
|
|
}
|
|
|
|
class PointManager<T> where T : IPoint
|
|
{
|
|
readonly T point; // this could be a struct
|
|
public PointManager(T point)
|
|
{
|
|
this.point = point;
|
|
}
|
|
|
|
public void MovePointVertically(int newX) // assignment has been removed
|
|
{
|
|
Console.WriteLine(point.X);
|
|
}
|
|
}
|
|
----
|
|
|
|
or
|
|
|
|
|
|
----
|
|
interface IPoint
|
|
{
|
|
int X { get; set; }
|
|
int Y { get; set; }
|
|
}
|
|
|
|
class PointManager<T> where T : class, IPoint
|
|
{
|
|
readonly T point; // this can only be a class
|
|
public PointManager(T point)
|
|
{
|
|
this.point = point;
|
|
}
|
|
|
|
public void MovePointVertically(int newX)
|
|
{
|
|
point.X = newX; // this assignment is guaranteed to work
|
|
Console.WriteLine(point.X);
|
|
}
|
|
}
|
|
----
|
|
|
|
|
|
|
|
ifdef::env-github,rspecator-view[]
|
|
'''
|
|
== Comments And Links
|
|
(visible only on this page)
|
|
|
|
include::comments-and-links.adoc[]
|
|
endif::env-github,rspecator-view[]
|