While the properties of a readonly
reference type field can still be changed
after initialization, those of a readonly value type 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.
There are two ways to fix this issue:
class
interface IPoint
{
int X { get; set; }
int Y { get; set; }
}
class PointManager<T1, T2>
where T1 : IPoint
where T2 : IPoint
{
readonly T1 point1; // this could be a struct
readonly T2 point2; // this could be a struct
public PointManager(T1 point1, T2 point2)
{
this.point1 = point1;
this.point2 = point2;
}
public void MovePoints(int newX)
{
point1.X = newX; //Noncompliant: if point is a struct, then nothing happened
point2.X = newX; //Noncompliant: if point is a struct, then nothing happened
}
}
interface IPoint
{
int X { get; set; }
int Y { get; set; }
}
class PointManager<T1, T2>
where T1 : IPoint
where T2 : class, IPoint
{
readonly T1 point1; // this could be a struct
readonly T2 point2; // this is a class
public PointManager(T1 point1, T2 point2)
{
this.point1 = point1;
this.point2 = point2;
}
public void MovePoints(int newX) // assignment to point1 has been removed
{
point2.X = newX; // Compliant: point2 is a class
}
}