Quick Question: Why I am able to change his private field? My mind is stuck. It’s weird.
Here is an example code i wrote:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class example : MonoBehaviour
{
//Private fields
private float thing;
private int secret;
//A public method for setting the private field "secret" for outsiders
public void ChangeSecret(int newSecret)
{
secret = newSecret;
}
// A public method
public void foo ()
{
example otherExample = new example(); //I just created another instance of example. I may have got it from code
//(like search for other example instances at the scene)
//It is just for demonstration purposes
secret = 10; //changing my own private field
otherExample.secret = 5; //!!How i can change his private field? Isn't it private??
otherExample.ChangeSecret(5); //This should be the only way I could change it, right?
}
}
Interesting… feature (bug?): since your method where you create the example is inside the same class, so you technically still are in the same scope. In fact, if you just copy the content for foo() inside another class, the compiler will give you an error.
I don’t know if this is a bug or a feature, but it’s really interesting!
I did tried to do the same thing inside a script other than example and indeed the compiler said i dont have access. But when i am inside the script this happpens…
A class can always change it’s own variables, so I don’t know why you’re surprised here.
When declaring variables, you must also declare the accessibility level of the variable by putting private, protected or public. You may want any of those for a variety of reasons, such as simplifying your public API to the class - like, why would anyone want to see this? If it’s only relevant to internal processes then it should probably be private. If it’s a virtual class and will be overridden then maybe protected is necessary because the child class needs to see that internal value too. Or, if some user needs to access that variable directly to do something then it must be public.
In C#, the private and protected accesibility modifiers, apply their restrictions per Type, not per instance.
There is no such thing as being able to “protect” read/write of variables in a per instance basis. They are just per Types. So any Type can modify a private value either for its own instance, or another instance of the same type,
That is not accurate unless the class/variable is static. If the class is static, there would only be one instance so the point is moot.
MyClass can always say this.m_myPrivateVariable = 42 but it cannot say OtherInstanceOfMyClass.m_myPrivateVariable = 42 becuase it does not have proper scope to it.
That is not accurate unless the class/variable is static
This is legal c# code
public class Foo
{
private float _someFloat;
public void DoSomething(Foo otherFoo)
{
otherFoo._someFloat = 3;
}
}
Furthermore, it is also allowed for derived types, as long as the field you are accessing was declared on the Type that is modifying it.
public class Bar : Foo { }
public class Foo
{
private float _someFloat;
public void DoSomething(Bar otherBar)
{
otherBar._someFloat = 3;
}
}
I agree that exists a common pattern where static methods modify private instance fields of their own type, but is not restricted to static. Accesibility modifiers are applied per Type scope, not instance
Wow! I actually had no idea it was by Type. I guess I just never really tried it because… why? Interesting to know this.
protected still restricts the access in its own functions. We can call the base functions of Foo to change something on Foo, but calling Bar.SomethingElse() would not allow access to Foo’s private variables - just protected even though it inherits.
For protected is still legal as long as the type that modifies the variable belongs to the same inheritance chain. This means that Bar cannot modify a Foo protected field (because it doesnt know if it is also Bar) But it can modify that field it type is Bar or upper.
public class Foo
{
protected float protectedAtFoo;
}
public class Baz : Bar { }
public class Bar : Foo
{
public void DoSomething(Foo someFoo)
{
someFoo.protectedAtFoo = 3; // does not compile
}
public void DoSomething(Bar someBar)
{
someBar.protectedAtFoo = 3; // compiles
}
public void DoSomething(Baz someBaz)
{
someBaz.protectedAtFoo = 3; // compiles
}
}
The other one I find enormously helpful is being able to access private variables in static methods within the class. Whenever I need to do an AddComponent() and it needs a little bit of extra setup, I use this to keep the setup entirely local to the class file as well as to ensure I have 100% of what I need before making the thing… tidy! This is an example codelet:
And just for completeness I’ll mention the readonly attribute, which some folks swear by but isn’t super-helpful in Unity because Unity classes don’t let you write constructors, generally speaking, leaving you only declarations where you can set the value… which then is not really all that different from a const… so why not make it a const?
Const doesnt let you set the value from the constructor which is what you do when using DI, readonly keyword is very useful in vanilla c# in conjunction with dependency management