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::rspecator-view[]
== Comments And Links
(visible only on this page)

include::comments-and-links.adoc[]
endif::rspecator-view[]
