Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>If <code>s1</code> and <code>s2</code> are structs of type <code>Foo</code>, with fields <code>f1</code>, <code>f2</code>, and <code>f3,</code> of types <code>t1</code>, <code>t2</code>, and <code>t3</code>, the statement <code>s1 = s2</code> is semantically equivalent to</p> <pre> s1.f1 = s2.f1; s1.f2 = s2.f2; s1.f3 = s2.f3; </pre> <p>except that one should make no assumption about the order of the assignment operations (or even the relative ordering of reads and writes; the generated code might, for example, read all three fields into registers, and then write all three fields). All fields will be copied, independent of whether they are public or private, mutable or so-called immutable. No property getters or setters will be called; neither the source nor destination struct will receive any notice that the fields of the structs are being duplicated or overwritten.</p> <p>A statement <code>this = new Foo(whatever);</code> is in C#(*) equivalent to</p> <pre> Foo temp; call Foo's constructor (out temp, whatever); this.f1 = temp.f1; this.f2 = temp.f2; this.f3 = temp.f3; </pre> <p>(*) Struct constructor semantics in vb.net are different</p> <p>As above, the field assignments are done without regard for whether the fields are public or private, and without regard for whether they are supposedly immutable.</p> <p>One reason I believe (contrary to the view of some other people) that structs should often expose mutable fields is that syntax like:</p> <pre> // Assume myKVP is a field of type KeyValuePair&lt;Wizzle, int&gt; rr = new KeyValuePair&lt;myKVP.Key, myKVP.Value+1&gt;; </pre> <p>makes it appear as though <code>myKVP</code> will refer to a different instance after the assignment from what it held before, when what is actually happening is:</p> <pre> // Assumes backing fields are named _Key and _Value // Note that C# won't allow one to write private fields directly, but the // act of copying one struct instance to another copies all the fields, // public and private, from the source instance to the destination. KeyValuePair&lt;Wizzle, int&gt; temp; temp._Key = myKVP.Key; // Constructor has access to backing fields temp._Value = myKVP.Value+1; myKVP._Key = temp._Key; // Struct assignment copies all fields, public and private myKVP.Value = temp.Value; </pre> <p>In other words, the statement does not make <code>myKVP</code> report to a different instance; instead, it creates a new instance, <i>mutates</i> the old instance by overwriting its fields with those of the new instance, and then discards the new instance. If some code was evaluating <code>myKVP.ToString()</code> while the above assignment took place, the mutation would affect the instance of <code>myMVP</code> that was being printed.</p> <p>Structs can have useful semantics, but so-called "immutable" structs aren't. Non-trivial structs (those for which it's possible to create a value different from the default) are mutable if and only if they are kept in mutable <i>storage locations</i>, regardless of any semantics imposed by the type. Self-mutating structs, i.e. structs which mutate <code>this</code> in any methods except in constructors and property setters, can have some unexpected behaviors because compilers have no way of forbidding the invocation of other methods which will mutate <code>this</code> on immutable struct <i>instances</i>. Public exposure of struct fields, however, does not pose any such danger. Since all fields of a mutable instance of a non-trivial struct are inherently mutable, regardless of any attempts the struct might make to allow mutation, and all fields of an immutable instance of a struct are immutable even if they're exposed, a struct which endeavors to make its fields "immutable" is really telling a lie. A lie which may at times be useful (e.g. if field contents are supposed to obey certain invariants) but which shouldn't be told without some real cause.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload