title: Best practice for implementing constant references in C++/CLI
body: <p>In native C++ it often makes sense to return an object as a constant reference. Consider class A supplying read-only-access to an instance of class B:</p>
  
  <pre><code>class B {
  public:
    int X;
  
    B(int x)
      : X(x)
    {}
  
    B(const B &amp;b) // copy constructor
      : X(b.X)
    {}
  
  };
  
  class A {
  private:
    B &amp;b;
  
  public:
    A(int x)
      : b(*new B(x))
    {}
  
    const B &amp;GetB()
    {
      return b;
    }
  };
  </code></pre>
  
  <p>Now a client has the choice to read A's B-data either very efficiently by reference, or create it's own copy if needed:</p>
  
  <pre><code>A a1(1);
  const B &amp;b1 = a1.GetB(); // constant reference
  // b1.X = 2; // compilation error
  
  B b2 = a1.GetB(); // through copy constructor
  b2.X = 2; // ok, but doesn't affect a1
  </code></pre>
  
  <p>In either case, it's guaranteed that nobody from outside is able to change the data within A's member instance of B. So, this is a perfect solution.</p>
  
  <p>An equivalent CLI construct would look like this at a first glance:</p>
  
  <pre><code>public ref class B {
  public:
    int X;
  
    B(int x)
      : X(x)
    {}
  
  };
  
  public ref class A {
  private:
    B ^b;
  
  public:
    A(int x)
      : b(gcnew B(x))
    {}
  
    const B %GetB()
    {
      return *b;
    }
  };
  </code></pre>
  
  <p>But this doesn't make very much sense, since it works in C++/CLI only. When you reference it from a different .NET language, such that C# or VB.NET, you won't see a GetB implementation at all. Ok, try this instead:</p>
  
  <pre><code>  const B ^GetB()
    {
      return b;
    }
  </code></pre>
  
  <p>The managed pointer is constant as expected within the same assembly:</p>
  
  <pre><code>A ^a1 = gcnew A(1);
  
  const B ^b = a1-&gt;GetB(); // ok
  b-&gt;X = 2; // error C3892: you cannot assign to a variable that is const
  
  // error C2440: 'initializing' : cannot convert from 'const B ^' to 'B ^'
  B ^b = a1-&gt;GetB();
  </code></pre>
  
  <p>At the same time in another .NET assembly (even when using C++/CLI), the constance is lost. Indeed, the following works within a second assemply referencing the one containing class A:</p>
  
  <pre><code>A ^a1 = gcnew A(1);
  B ^b2 = a1-&gt;GetB();
  b2-&gt;X = 2; // b-&gt;X changed within a1
  </code></pre>
  
  <p>Surprisingly, that way you have "more" access to an object from outside the assembly than from inside, because the language construct behaves differently. Is this an intended behavior?</p>
  
  <p>Anyway, what's the best practice to transform the idea of a constant return object into the .NET world? How would you implement class A in CLR style, providing that class B supports a huge amount of data (too much to copy) that shouldn't be changed from outside class A?</p>