This question already has answers here:
Why are private fields private to the type, not the instance?
(10 answers)
Closed 9 years ago.
public class Class1
{
private object field;
public Class1(Class1 class1)
{
this.field = class1.field;
}
private void Func(Class1 class1)
{
this.field = class1.field;
}
}
This code compiles and works. But why? I always thought that private members are only accessible within the class scope. Also MSDN says so:
The private keyword is a member access modifier. Private access is the least permissive access level. Private members are accessible only within the body of the class or the struct in which they are declared
That's because by marking it as private, you are telling the compiler that only Class1 may access that variable. Even though your constructor is public, the variable itself is still declared within Class1 and so it has access to modify it.
Even though they could be two different instances, they are the same variable declaration.
However, if I did this from Class2, it would not work:
Class1 c1 = new Class1();
c1.field = "value"; // Won't compile
This is actually explained from your quote:
Private members are accessible only within the body of the class
The private keyword means its private for the class (as stated in MSDN), not the object. So one instance of a class can access the private members of another instance of the class.
It works because an object can hold anything. If you pass in class1 and the object field is null then the object field will remain null. If that makes sense?
As long as the code that access that private field is in Class1, you can use it. That's what private means - it's accessible from anywhere inside those {}
Related
I'm a little bit confused with nameof() operator. So for example I can't use class's private fields in nameof() in another class, but I can use public non static fields using non static property, so I don't need instantiated object.
Is it consistently? Why member access modifier does matter for nameof()?
class A
{
private int X;
public int Y;
public A()
{
var x = nameof(A.X);//OK
var y = nameof(A.Y);//OK
}
}
class B
{
public B()
{
var x = nameof(A.X);//Compilation error
var y = nameof(A.Y);//OK
}
}
The purpose of access modifiers like private is to hide the implementation details. They are saying "Nope, you don't need to know this. This is implementation detail". That's why nameof is not allowed to access private properties. Whatever class you are in, that class should not know about the implementation details of some other class.
Static vs non-static is different. Its purpose is not to hide something that you don't need to know about. Its purpose is just to distinguish between members that belongs to instances of the class and members that belongs to the class itself. All you want here is just the name of that member, which requires no instances to be created, so why disallow you? Note that the member is accessible i.e. it's not something you shouldn't know about.
Field X in class A is private. door is locked, you cant access it no matter what you do.
This is not a nameof problem, its Access Modifier problem
Access Modifiers (C# Programming Guide)
All types and type members have an accessibility level, which controls
whether they can be used from other code in your assembly or other
assemblies. You can use the following access modifiers to specify the
accessibility of a type or member when you declare it:
and
public The type or member can be accessed by any other code in the same assembly or another assembly that references it.
private
The type or member can be accessed only by code in the same class or struct.
protected The type or member can be accessed only by code in the same class, or in a class that is derived from that class. internal
The type or member can be accessed by any code in the same assembly,
but not from another assembly.
protected internal The type or member can be accessed by any code in the assembly in which it is declared, or from within a derived class
in another assembly.
private protected The type or member can be accessed only within its declaring assembly, by code in the same class or in a type that is
derived from that class.
Not a direct answer to your question, but I usually get around this but using a static helper class:
class A
{
public static class Properties
{
public const string X = nameof(A.X);
}
private string X { get; }
}
Then using
A.Properties.X
It's a little bit more verbose, but still enables refactoring tools to work effectively.
This question already has answers here:
What fields can a nested class access of the class it's nested in?
(3 answers)
Closed 6 years ago.
What is the best way to access fields from a nested class?
class FirstClass
{
public int FirstClassField;
public FirstClass()
{
this.FirstClassField = 5;
}
class SecondNestedClass
{
int SecondClassField;
public SecondNestedClass()
{
FirstClassField = 6;
}
}
}
The error:
An object reference is required for the non-static field, method, or property 'FirstClass.FirstClassField'
The goal is to be able to use and modify FirstClass fields from the Nested class.
For my purposes, the first class is a form
public partial class MyForm : Form
And passing a reference of MyForm is not possible since it is readonly.
Any ideas?
The nested class is just a nested type, nothing like a nested instance. So if you create an instance of SecondNestedClass, there is no instance of FirstClass involved. So for which FirstClass instance do you want to set FirstClassField?
SecondNestedClass and FirstClass are completely different and independent types. FirstClassField is not a member of SecondNestedClass.
The only difference to non-nested types is that an instance of SecondNestedClass is allowed to access private fields of an instance of FirstClass. But you still need an instance at all to access its fields.
How to solve this depends on what you actually are trying to achieve. You could consider providing an instance of FirstClass to the constructor of SecondNestedClass:
public SecondNestedClass(FirstClass first)
{
first.FirstClassField = 6;
}
This question already has answers here:
How to instantiate an object with a private constructor in C#?
(4 answers)
Closed 7 years ago.
I want to access some of the private members of a class which has its constructor defined as private. How do I create the PrivateObject for such class so that I can access its private members ?
I tried something like this but I cannot instantiate the class "MyClass1" so I am not able to instantite the PrivateObject.
MyClass1 myClass = new MyClass1(); //gives compilation error
PrivateObject po = new PrivateObject(myClass); //gives compilation error
Is there any workaround for this ?
Class with private constructor can only create itself from its own static method. For example:
class MyClass1
{
private MyClass1()
{
}
public static MyClass1 CreateInstance()
{
return new MyClass1();
}
}
It's private members like fields or properties are always accessible only from inside of the class (unless you make some tricks with reflection). If the field is protected you can access it by deriving from this class. All other way it's by design created to restrict access to those fields and you should not try accessing them from the outside.
Edited: now I noticed you use PrivateObject class which is created to make reflection trickes mentioned above. So now you only need to create instance. You should check what is the designed way of initializing this object probably by some static method?
Or check this link for more hacks with reflaction and using Activator: http://www.ipreferjim.com/2011/08/c-instantiating-an-object-with-a-private-constructor/
This question already has answers here:
What are the default access modifiers in C#?
(10 answers)
Closed 8 years ago.
I'm new to Programming! Ignore if it a silly question. But leave a comment.
Is it possible to declare an access specifier to object instances in C#?
OR is there any default specifiers for that ?
class Person
{
public int age;
}
class Program
{
static void Square(Person a, Person b) // Here note down "a" and "b" are instances
{
a.age = a.age * a.age;
b.age = b.age * b.age;
Console.WriteLine(a.age+" "+b.age);
}
}
The default for classes is internal, meaning, they can only be accessed by types in the same assembly. If a class is not contained inside other class it can also be public, in which case, it is accessible by any type. If it is declared inside other class, then it can also be protected, only accessible by the containing class or its subclasses, private, only accessible by the containing class, public, freely accessible or protected internal, meaning, accessible by the declaring class, its subclasses or types in the same assembly. The default for nested classes is private.
A member (property, field or event) can also be private (default), public, protected, internal or protected internal.
When you instantiate from a class, you can define its access scope by modifiers (This modifier is for type member(reference)).
Modifiers are used to modify declarations of types and type members
Look at following examples:
1)
class Employee
{
private Person person; //private is modifier for person type member, not for Person class
}
2)
static void Square(Person a, Person b){...} //The access scope for a and b is equal with method scope
For example this is not instance modifier:
public class Person
{...}
An example is worth a thousand stupid questions so:
public class OuterClass
{
public static class InnerClassEventArgs : EventArgs
{
public static int SomeInt;
}
}
and in a galaxy far far away:
public void SomeFunkyFunc()
{
OuterClass Instance1;
OuterClass Instance2;
Instance1.InnerClassEventArgs.SomeInt = 1;
Instance2.InnerClassEventArgs.SomeInt = 2;
//WHAT WOULD Instance1.InnerClassEventArgs.Someint == ?
}
Yes, I realize now that I've typed this that I've almost coded all I need to answer my own question. I'd rather not create a new project and go through the trouble if someone smarter than me knows off the top of their head.
Instance1.InnerClassEventArgs.SomeInt would equal 2. Static fields are shared across all instances of the class -- or as MSDN puts it:
The static member is always accessed by the class name, not the instance name. Only one copy of a static member exists, regardless of how many instances of the class are created.
Note that your specific example won't compile -- you'll get an error message that says "Cannot access static class 'InnerClassEventArgs' in a non-static context."
You'd have to use the following code instead, which hopefully makes the behavior more understandable:
OuterClass.InnerClassEventArgs.SomeInt = 1;
OuterClass.InnerClassEventArgs.SomeInt = 2;
A static class has exactly one instance, "shared" by all its usages (in your case, all instances of OuterClass). Therefore, the state of that object will be the sum of all changes made by any usage. In this simple example, SomeInt will be 2, regardless of which OuterClass instance you used to access it again (Instance1 or Instance2).
I'm conveniently ignoring all of the following:
A static class cannot inherit from any other class. InnerClassEventArgs thus cannot inherit from EventArgs.
Instance1 and Instance2 are not initialized; this will cause its own compile-time error if you use ReSharper ("X may not be initialized before accessing").
Static members (including nested static classes) cannot be accessed based on any one instance; you would access InnerClassEventArgs in static context.