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
{...}
Related
I understand that a private protection level is meant to stop any child accessing private parent variables.
But isn't there a way to do it with accessors and mutators(get and set)? I have to have some kind of way to change a private string because that is the homework.
I have a public abstract pet class with a private string for a name. I want to create a dog and use that string name. I can't figure it out though. Since it is homework, I understand I cannot be given code or anything, but could someone point out the method to do this so I can google it? All my searches just imply that it is impossible.
Here's my code if it will help.
edit
I can't just make it protected.
public abstract class Pet
{
private string name;
private string species;
public abstract void speak();
public abstract void play();
public abstract void info();
}
Part of the child dog class...
class Dog : Pet
{
public Dog(string xname, string xspecies)
{
this.name = xname; // this is where I'm having trouble.
}
Let's make sure that you have a clear and accurate understanding; many beginners are taught subtle falsehoods.
I understand that a private protection level is meant to stop any child accessing private parent variables.
That's a correct summary of the intention of the feature. Basically you are saying that access control modifiers are for controlling access, which should not be a surprise.
However there are two subtleties that I want to point out here.
The first is that access modifiers control access to the names of things, not to the things. When you have a member named foo, the name foo may only be used to refer to that member from within the accessibility domain of that member. The "accessibility domain" is a region of program text; the accessibility domain of a private member is the text of the type which declares the member.
If you have come up with some other way to refer to a member, that mechanism is not controlled by the accessibility modifier. The only thing an accessibility modifier controls is where the name may be used in the text of the program.
Make sure that is clear in your head.
Second, you note that a private member is not accessible to a "child", by which I assume you mean a derived class. There is a situation in which a derived class can access private member by name. Given what I've said so far, you should be able to deduce what it is. Give it some thought and then read on.
I said that a private member is accessible by name only inside the text of the declaring type, so if a private member is accessible by name by a derived class, the derived class must be inside the text of the declaring type:
class Base
{
private static int x;
class Derived : Base
{
static void M() { Console.WriteLine(Base.x); }
}
}
This is legal because x is used by name inside its accessibility domain.
So, how do you do your homework problem? There are only two ways:
(1) Put Dog inside of Pet; any Dog then has access to all the private members of Pet. This is a "for advanced players only" feature of C# and almost certainly not what your instructor is looking for. But it is a really powerful technique and I use it frequently, so keep it in mind for your later career; in particular, when you learn about the "factory pattern" you can pull out of your back pocket the knowledge that putting the derived classes inside the base class is a good trick for making the factory pattern work well.
(2) Make some accessor mechanism for the private member, and make that accessor mechanism's name protected, internal, or public.
Typically you'd use a property. You make an property with a read-only accessor in C# like this:
class Base
{
private int x;
public int X { get { return x; } }
}
Or, in more modern versions of C# you can use this short form:
public int X => x;
And now code outside of Base cannot use x by name, because that is outside of the accessibility domain of Base.x. But X has an unrestricted accessibility domain, so it can be used anywhere you like.
That's a read-only accessor. To make a write accessor you add a setter:
public int X
{
get { return x; }
set { x = value; }
}
Notice that setters have a magic value name that is the value that is to be assigned to the property.
There are other ways to make accessors but this is by far the most common.
While we are looking at your code, a couple other things:
(1)
public abstract void speak();
public abstract void play();
public abstract void info();
Public methods should be PascalCasedLikeThis, not lowercase, in C#. It's just an arbitrary convention that makes it easier to read your code.
(2)
Why is info void returning? Surely it should be returning some info.
(3)
class Dog : Pet
Is your intention to further subclass Dog? Probably not, because it is not abstract. Consider marking classes not intended to be subclassed as sealed, so that you do not have to worry about designing the class for safe inheritance.
I think you're looking for the protected access modifier, which means the variable is accessible within its class and by derived class instances:
public abstract class Pet
{
protected string name;
protected string species;
public abstract void Speak();
public abstract void Play();
public abstract void Info();
}
class Dog : Pet
{
public Dog(string xname, string xspecies)
{
name = xname;
species = xspecies;
}
// Implementation of Pet here
}
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;
}
I have been learning C# for two weeks now, though it is not my first either second language. I have been wondering about the static word. I know I should have researched about this word long before...but this is the first time I realized how much confusing this word is for me. For what I have read:
A static class is a class which does not need to be instanciated to be used (
Class with single method -- best approach? ). This may have some advantages and some disadvanatges regarding testing, polymorphism etc.
But the static word can be applied also to classes, fields, methods, properties, operators, events and constructors !!! ( https://msdn.microsoft.com/en-us/library/98f28cdx%28v=vs.80%29.aspx ). Example:
Property:
private static string s = "";
Method:
public static void helperMethod() {
Console.WriteLine("Whatever");
}
Does the word static have a global meaning or employed in differents parts of the code the meaning can change?
class modifier
When static is applied to a class it indicates four attributes.
Contains only static members.
Cannot be instantiated.
Is sealed.
Cannot contain Instance Constructors.
property or function modifier (and events and methods)
When applied to properties and functions, e.g.
public Thing
{
static int SharedCount { get; set; }
static string GenerateName()
{
// ...
}
}
it means that the properties and functions will be accessible via the type name, without instantiating the class. This properties and functions will not be accessible via an instance of the class. So, both
var i = Thing.SharedCount;
var s = Thing.GenerateName();
Are valid and correct statements, Where as
var i = new Thing().SharedCount;
var s = this.GenerateName();
are both incorrect.
Code in functions and properties declared with the static modifier cannot access non-static members of the class.
member variables
Member variables declared with a static modifier, e.g.
class Thing
{
private static int sharedCount = 0;
private static readonly IDictionary<string, int> ThingLookup =
new Dictionary<string, int>
{
{ "a", 1 },
{ "b", 2 }
};
}
are shared by all static functions and properties and by all instances of the class.
static constructors
When applied to constructors, e.g.
class Thing
{
static Thing()
{
\\ Do this once and first.
}
}
static means the constructor will run once per AppDomain, when the type is first accessed. There are special edge cases around this.
operators
When an operator is overloaded for a type, this is always declared as static, e.g.
public static Thing operator +(Thing left, Thing right)
{
// Something special to do with things.
}
It is not logical for this to be declared at an instance level since operators must apply to types.
These distinctions are explained here, here, here and here.
Static members are items that are deemed to be so commonplace that there is no need to create an instance of the type when invoking the member. While any class can define static members, they are most commonly found within utility classes such as System.Console, System.Math, System.Environment, or System.GC, and so on.
Also the static keyword in C# is refering to something in the class, or the class itself, that is shared amongst all instances of the class. For example, a field that is marked as static can be accessed from all instances of that class through the class name.
Quick answer: No static remains the same contextually everywhere :
From dotnetperls:
These are called with the type name. No instance is required—this makes them slightly faster. Static methods can be public or private.
Info:
Static methods use the static keyword, usually as the first keyword or the second keyword after public.
Warning:
A static method cannot access non-static class level members. It has no this pointer.
Instance:
An instance method can access those members, but must be called through an instantiated object. This adds indirection.
C# program that uses instance and static methods
using System;
class Program
{
static void MethodA()
{
Console.WriteLine("Static method");
}
void MethodB()
{
Console.WriteLine("Instance method");
}
static char MethodC()
{
Console.WriteLine("Static method");
return 'C';
}
char MethodD()
{
Console.WriteLine("Instance method");
return 'D';
}
static void Main()
{
//
// Call the two static methods on the Program type.
//
Program.MethodA();
Console.WriteLine(Program.MethodC());
//
// Create a new Program instance and call the two instance methods.
//
Program programInstance = new Program();
programInstance.MethodB();
Console.WriteLine(programInstance.MethodD());
}
}
Output
Static method
Static method
C
Instance method
Instance method
D
In C#, data members, member functions, properties and events can be declared either as static or non-static.
Only one copy of static fields and events exists, and static methods and properties can only access static fields and static events.
Static members are often used to represent data or calculations that do not change in response to object state.
Static can be used in following ways:
Static data members
Static constructor
Static Properties
Static methods
More references :
MSDN
Static
Static in c#
What is static ?
The static keyword means generally the same everywhere. When it is a modifier to a class, the class's members must also be marked static. When it is a modifier to a member, (fields, properties, methods, events etc.) the member can be accessed using the following syntax:
ClassName.memberName
Note that operators must be declared static and extension methods must be in a static class which means it also has to be static.
Word static speaks for itself. If you have something that may change for every new object of some type - it's instance member and if it stays the same for all instances - it's static member.
From MSDN :
It is useful to think of static members as belonging to classes and
instance members as belonging to objects (instances of classes).
Source : static and instance members
Static members can be accessed via class object, something like MyClass.MyMember when instance members are only accessible on instance of a class (new MyClass()).MyMember
It's obvious that compiler takes some time to create instance and only then you can access its properties. So instance members works slower than static members.
In simple words , static property is not being changed across the classes , if your static member is affecting multiple classes once you change the value of it, it will be changed in every single class that is being affected by it.
Static method has to be static if you tend to use it in a static context (static class or so..)
Static class is the one which cannot be instantiated, e.g. static class Car{} this car will always have the same properties ( colour, size...)
There are many concepts related to Static keyword.
This answer will resolve your confusion about static.
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 {}