0

Possible Duplicate:
Why and how does C# allow accessing private variables outside the class itself when it’s within the same containing class?

This has completely passed me by some how, apparently the code below is legal, and more surprising is legal from framework 2 onwards...

public class Magic
{
    private readonly int _anInt;
    private readonly string _aString;

    public Magic(int anInt, string aString)
    {
        _anInt = anInt;
        _aString = aString;
    }

    public Magic(Magic toCopy)
    {
        _anInt = toCopy._anInt; // Legal!
        _aString = toCopy._aString; // Legal!
    }

    public void DoesntWorkMagic(Magic toCopy)
    {
        _anInt = toCopy._anInt; // edit: Will work if not readonly. 
        _aString = toCopy._aString;
    }

    public int AnInt { get { return _anInt; } }

    public string AString { get { return _aString; } }
}

What's going on? I've seen so many copy constructors doing excess work over the years, I wouldn't have believed this work until I came across it. Are there any caveats to its use (besides the obvious threading issues)?

6
  • 7
    Well, to quote MSDN on the private modifier: The private modifier makes a member of a class visible only within that **class**. Note how it says class, not instance... Commented Jan 25, 2013 at 11:20
  • I dont see anything wrong with the code, except that you might was to use MemberwiseClone() instead. Commented Jan 25, 2013 at 11:20
  • In case you are interested, Scala, has a modifier (private[this]) that lets you make a field accessible to only the same instance. (It's the only language I know of that has.) Commented Jan 25, 2013 at 11:22
  • A side note wold be that, conventionally (loosely), using static members in the form of FromX(X x) would be preferable over a 'copy constructor' (just based on my experience in the .NET world, don't have any references or anything). Commented Jan 25, 2013 at 11:23
  • @GrantThomas: Objective-C uses something similar, for example NSArray's initWithArray. Commented Jan 25, 2013 at 11:29

2 Answers 2

4

private is not object level, it is class level, so objects of the same class know about their private aspects, so are allowed to change private things on other object of the same class.

private prevents other types poking around where they shouldn't go.

Sign up to request clarification or add additional context in comments.

2 Comments

I've changed the question a little. There is now a method :DoesntWorkMagic which doesn't allow access.
As pointed out below, it will work if I hadn't made it read only.
0

There is no "copy constructor" in C#. There are only constructors.

In your code you have the argument toCopy that is a instance of the current class Magic. So as it is the same class you can access the private fields toCopy._anInt and toCopy._aString (it is a modifier that makes the field visible all the instances of the same class).

And as you are in a constructor, you can set the fields _anInt, _aString of the new instance.

The readonly keyword just say: "this field can only be set in the constructor of the instance.

4 Comments

Yes, Now look at the edit and see the method which is not a constructor that will not compile. I call it a copy constructor because it is copying a source object, the access to its private members is only available in a constructor, not from other methods.
I though you were confusing with C++ copy constructors. Yes, DoesntWorkMagic will not compile because of readonly (DoesntWorkMagic is not a constructor) not because of the private.
There is no automatically-generated copy constructor in C#, but you can write one yourself, as explained by this Microsoft article: msdn.microsoft.com/en-us/library/ms173116%28v=vs.110%29.aspx
Seriously I feel like I've just noticed a glitch in the matrix. As if this was totally impossible yesterday, and today it isn't. I've always used _ for private members, so it's possible that's why I wouldn't have seen them available through intellisense. Matt, I just used the term "copy constructor" because the example was a constructor that copies and my original example was bad so I didn't realise the private members were accessible from methods that were not ctors. Live and learn :)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.