can we access a private variable using an object - c#

We cannot access a private variable of a class from an object, which is created outside the class, but it is possible to access when the same object is created inside the class, itself. why??
class Program
{
private int i;
public void method1()
{
Program p = new Program();
p.i = 5; // OK when accessed within the class
}
}
class AnotherClass
{
void method2()
{
Program p = new Program();
p.i = 5; //error because private variables cannot be accessed with an object which is created out side the class
}
}
Now I think every one got my point??
In both the cases above, we are accessing the private variable 'i' through the object 'p'. But inside class it is allowed, outside the class not allowed. Can anybody tell me the reason behind this??

You can access i from within the class because private members can only be accessed by members of the class. In this case it looks strange because p is a different object than the object that accesses the variable, but its still the same class and the restriction is on the class level not on the object level.
class Program
{
private int i;
public void method1()
{
Program p = new Program();
p.i = 5; // OK when accessed within the class
}
}
You can not access i from within another class (unless it is an inner class but that's a different story). Which is completely as expected.
class AnotherClass
{
void method2()
{
Program p = new Program();
p.i = 5; //error because private variables cannot be accessed with an object which is created out side the class
}
}
I understand the point you want to make. The restriction on class level looks counter intuitively. And maybe this is wrong. But the member variables are still only accessible from within the class, so you still have total control to guarantee the encapsulation of your privates.

why??
It's true by the language specification. The access modifier private has the semantics that only the class or struct declaring a member is allowed to access that member.
I suggest reading the specification for details. In particular, check out
§3.5.1 Declared Accessibility
§3.5.4 Accessibility constraints
§10.2.3 Access Modifiers
§10.2.6.2 Declared Accessibility
§10.2.6.5 Access to private and protected members of the containing type

In both the cases above, we are accessing the private variable 'i' through the object 'p'. But inside class it is allowed, outside the class not allowed. Can anybody tell me the reason behind this??
Because access modifiers don't pertain to the object, they pertain to the class (or assembly, for the internal modifier).
Even if you access it from a different object, or a static context, as long as you stay in the same class, accessing a private member will work. It's private to the class, not its instances.

You are maybe confusing object and class, public/private/protected/internal affect class visibility not object visibility. That means an object of a class can access attributes of another object of the same class, even if they are private.
I am not sure I understood your question correctly...

if accessing outside the class is the option required then try properties.

This belongs to OOP. The answer would be because its private, otherwise if all private variables would be accessable from outside the class the object's concept wouldnt make any sense.

You Can Access the private variables in the following process also...
namespace OOPSProj
{
class Program
{
private int i;
public void Methode1()
{
Program objprog2 = new Program();
objprog2.i = 15;
Console.WriteLine("i= " + objprog2.i);
}
static void Main(string[] args)
{
Program objprog = new Program();
objprog.i = 10;
Console.WriteLine("i= " + objprog.i);
objprog.Methode1();
}
}
class Test
{
static void Main()
{
Program objproj3 = new Program();
objproj3.Methode1();
}
}
}

Related

How can I access a list that is created in a static object that is part of another class?

What I would like to do is to have a list that is in an object counts that is defined in the App class as a static when my application starts:
Here's the object:
public class Counts
{
public Counts()
{
public static List<CntQty> CardClicks2m;
}
}
In my application I declare this
am using the following code:
public partial class App : Application
{
public static Counts counts = new Counts();
public App()
{
}
}
Now I try to use load some data into the list but it gives me the error below. Note that this function is in another class.
public void GetClickHistory()
{
App.counts.CardClicks2m = db2.Query<CntQty>(sql);
The last line of the code is giving me an error saying
counts.CardClicks2m cannot be accessed with an instance reference;
qualify it with a type name instead.
I have tried a few different ways to make this work. One by removing the static and creating the object in the app constructor. This also didn't seem to work so I am hoping someone can point me in the right direction or at least suggest something.
i guess scope of variable is not right , you need to do like this
public class Counts
{
public static List<CntQty> CardClicks2m;
public Counts()
{
}
}
The error is pretty self explanatory, you cannot access a static property using an instance variable. all you need to do is use the typename. So this:
App.Counts.CardClicks2m
Becomes this:
Counts.CardClicks2m
You may need to specify the full namespace of the Counts class:
Some.Namespace.Counts.CardClicks2m
The error you are receiving is because you are trying to access to a static member from a instance object
public void GetClickHistory()
{
App.counts.CardClicks2m = db2.Query<CntQty>(sql);
EDITED after comments:
Try this (accessing the static member from the class):
public void GetClickHistory()
{
Counts.CardClicks2m = db2.Query<CntQty>(sql);
As CardClicks2m is declared static, it must be accessed from the class scope. If Counts class doen't have any other code, you can declare
public static class Counts
And there is not neccesary to create an instance of counts
public static Counts counts = new Counts(); //this is not neccesary
As your CardClicks2m-member is static there´s no need to have any instance of your Counts- or aven your App-class. The member exists once per appdomain however. Having said this in order to access CardClicks2m you don´t have to create an instance of your Counts-class within App.
Use this instead:
class MyClass
{
void DoSometjing()
{
Counts.CardClicks2m = db2.Query<CntQty>(sql).ToList();
}
}
Be aware to that Query will surely not return a List<CntQty>, but an IQueryable<CntQty>, that´s why you should call ToList afterwards.
Furthermore you can´t declare a member within a method or constructor. Thus declare it within the class´-body instead of the constructor:
public class Counts
{
public static List<CntQty> CardClicks2m;
public Counts() { /* any further initialzation */ } }
}

Inheritance - Can't access base class data member in derived class

One doubt in inheritance, I have two class named A and B.
A is Base Class and B is Derived Class.
B Class inheriting two data members and two member functions of A Class.
In derived class, accessing the static data member is Working but
accessing the non static data member gives error. This same case is
also for Member Functions. I can't access non static member function.
If i access either static or non static variable | function inside any of derived class function it working fine.
Why i can't access directly in a class. Why its not showing error when i access inside of any derived class function. Any one please clarify my doubts.
class A
{
protected string msg1;
protected static string msg2;
protected string alert1() {
return "Welcome";
}
protected static string alert2()
{
return "Welcome All";
}
}
class B : A {
string copyMsg1 = msg1;
string copyMsg2 = msg2;
string getMsg1 = alert1();
string getMsg2 = alert2();
void display() {
msg1 = "";
msg2 = "";
alert2();
}
}
This line is illegal:
string getMsg1 = alert1();
Because it is equivalent to
string getMsg1 = this.alert1();
and accessing this in a field initializer is illegal. Why? Because field initializers run before either the derived class constructor or the base class constructor, and therefore you could be calling a method that depends on the constructor having already run.
The correct solution is to put your initializations into the constructor:
class B : A {
string copyMsg1;
string copyMsg2;
string getMsg1;
string getMsg2;
public B()
{
this.copyMsg1 = this.msg1;
this.copyMsg2 = A.msg2;
this.getMsg1 = this.alert1();
this.getMsg2 = A.alert2();
}
The body of the constructor runs after the field initializers of the derived class, the field initializers of the base class, and the constructor body of the base class. The derived constructor body runs last, and therefore you know that all the stuff it accesses has already been created.
While we're at it: note that methods in C# traditionally begin with a capital letter.
Also, there is not really a good reason shown in this code to do the copying at all. You already have access to the base class members from the derived class, so why are you copying them into the derived class?
If i access either static or non static variable | function inside any of derived class function it working fine.
Why i can't access directly in a class. Why its not showing error when i access inside of any derived class function. Any one please clarify my doubts.
In other words you question is: Why can I access the static fields at the class level (outside of any methods or properties) but not instance fields.
Static fields are per class. You do not need an instance of the class but you need the class to be available. Therefore, if the class is available, then you can access it.
Now let's go to non-static fields. Here is your class, please note the numbers in comments:
class B : A {
string copyMsg1 = msg1; <-- 1. assign non-static to non static
string copyMsg2 = msg2; <-- 2. assign static to non static
string getMsg1 = alert1(); <-- 3. non static calling non-static
string getMsg2 = alert2(); <-- 4. non static calling static
void display() {
msg1 = "";
msg2 = "";
alert2();
}
}
This is NOT allowed because they are both instance fields (non-static), and there is no guarantee that there will be an instance of A available at this point.
This is allowed because instance fields can access static fields. But not the other way around because an instance may not be avaialbe. Instance fields, methods, and properties can access both static and non static.
This is NOT allowed because of item 1 above.
This is allowed because of 2.
Call the non-static method inside a setter method :
class A
{
protected string alert()
{
return "me";
}
}
class B :A
{
private string s;
private void setS()
{
s = alert();
}
}

Static property of inner static class of non-static class shared between instances of the non-static class?

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.

Difference between public and private variables

namespace hi
{
class hithere
{
public int numberOne = 12;
private int numberTwo = 12;
static void yo()
{
}
}
}
Can someone tell me the difference between the variables numberOne and numberTwo in this code excerpt?
From the accessibility levels at MSDN:
public Access is not restricted.
protected Access is limited to the containing class or types derived from
the containing class.
internal Access is limited to the current assembly.
protected internal Access is limited to the current assembly or
types derived from the containing
class.
private Access is limited to the containing type.
Public variables are accessible from out side classes but private one just accessible for current class and inner classes:
public class VarClass
{
public int publicID = 10;
private int privateID = 100;
public VarClass()
{
Console.WriteLine(publicID);
Console.WriteLine(privateID);
}
public class InnerClass
{
public InnerClass()
{
VarClass c = new VarClass();
Console.WriteLine(c.privateID);
Console.WriteLine(c.publicID);
}
}
}
public class OuterClass
{
public OuterClass()
{
VarClass c = new VarClass();
Console.WriteLine(c.privateID); // Compile Error
Console.WriteLine(c.publicID);
}
}
Other objects can access NumberOne, but they can't access numberTwo.
So I can do Your_Object.numberOne = 14; but I can't do Your_Object.numberTwo= 14;
Now I might be able to access the numberTwo through reflection depending on the permissions set up in the application, but I can't directly.
Variables in C#
Reflection in C#
Accessors in C#
in general, PUBLIC means any other code outside the class can change its value. PRIVATE are only able to be used/changed IN the class itself. Additionally, if you build classes that are derived from another, and you want the child-level class to be able to use/change values of its parent, but not other generic code outside the class, use PROTECTED.
Search for "Encapsulation".
There are so many easy materials to study it.
In the simplest terms numberOne being marked as public means that if you create an instance of your hithere class this member variable will be accessible. For example:
hithere h = new hithere()
h.numberOne = 42;
numberTwo being private means that this is not accessible and can only be used within the hithere class. So taking the above example further:
hithere h = new hithere()
h.numberOne = 42;
h.numberTwo = 84;
The last line would cause a compiler error as you cannot access numberTwo as this is private.
It is probably worth spending some time reading up on access modifiers, a quick google will find many examples, e.g:
http://www.devsource.com/c/a/Techniques/Understanding-C-Class-and-Member-Modifiers/
http://msdn.microsoft.com/en-us/library/ba0a1yw2%28v=vs.80%29.aspx
Additionally your hithere class does not have an access modifier defined therefore the compiler assumes this to be private. As such if you were to reference your library from another you would not be able to create instances of the hithere class.
public and private are access modifiers for members. This refers to who can access the members directly through code. public means that access is not limited so that anyone can access the member directly through code. private means that access is limited only to the containing class. So everyone can access numberOne directly through code, but only the containing class can access numberTwo directly through code.
There are a total of five access modifiers:
public: access is not limited
protected: access is limited to the containing class or classes derived from the containing class
internal: access is limited to the containing assembly
protected internal: this is an OR of protected and internal so that access is limited to the containing class or classes derived from the containing class OR the containing assembly
private: access is limited to the containing class
Note that the clause "directly through code" is critical here; it is possible to access these members using reflection.
The relevant section of the C# specification is §3.5, especially §3.5.2.
It means that if you have another class like this:
namespace hi
{
class hithere2
{
static void yo2()
{
hithere h = new hithere();
h.numberOne = 2;
h.numberTwo = 3;
}
}
}
The second one errors, but the first is OK.

C#: Can a base class use a derived class's variable in a static function?

Is there anyway of having a base class use a derived class's static variable in C#? Something like this:
class Program
{
static void Main(string[] args)
{
int Result = DerivedClass.DoubleNumber();
Console.WriteLine(Result.ToString()); // Returns 0
}
}
class BaseClass
{
public static int MyNumber;
public static int DoubleNumber()
{
return (MyNumber*2);
}
}
class DerivedClass : BaseClass
{
public new static int MyNumber = 5;
}
I'm trying to have it return 10, but I'm getting 0.
Here's where I'm using this: I have a class called ProfilePictures with a static function called GetTempSavePath, which takes a user id as an argument and returns a physical path to the temp file. The path base is a static variable called TempPath. Since I'm using this class in multiple projects and they have different TempPaths, I'm creating a derived class that sets that variable to whatever the path is for the project.
See Also
Why can’t I declare C# methods virtual and static?
Apart from the fact that has already been pointed out... that static variables are tied or bound to the specific class declaring them and cannot be overridden. Overriding/Polymorphism needs instances to work.
Your problem can be solved with a change in design.
string ProfilePictures.GetTempSavePath(SomeType UserId, string sBasePath)
if it just needs these 2 variables to compute the return value, you can keep it as a utility/static method. Now you can feed in different base paths..
Now it seems from your question, that you need to use this class in multiple projects (which have fixed base paths) and kind of hardcode the base path so that you dont have to specify it for each call.
Type/Class hierarchies should be defined based on behavior and not on data. Variables can handle change in data. Hence I'd suggest holding the basepath value as a static member variable, which is initialized from a resource file (DoubleClick your project properties node > Settings > Add a new Settings file > add a new setting called BasePath - string - Application scope - VALUE=C:\Users). Now you just need to tweak the app.config file for each project, no code changes, no hardcoding and not more than one type needed.
public class PathHelper
{
static string _sBasePath;
static PathHelper()
{
_sBasePath = Properties.Settings.Default.BasePath;
}
static string GetTempSavePath(string sUserId)
{
// dummy logic to compute return value, replace to taste
return Path.Combine(_sBasePath, sUserId.Substring(0, 4));
}
}
Hope that made sense
The problem is that you're re-declaring the static variable in the derived class. The MyNumber declaration in DerivedClass hides the declaration in the base class. If you remove that declaration, then references to the "MyNumber" in derived class static functions will refer to the base class variable. Of course, if you remove the declaration then you can't use a static initializer in the derived class.
You might want to consider requiring users to instantiate an instance of ProfilePictures rather than provide a static function for GetTempSavePath. That way you could overide the GetTempSavePath method to provide the correct TempPath. Or, you could simply set the value of the static path value in your derived class constructor.
Although it is possible to use inheritance with static members, you can't relly have polymorphic behavior without a "this" pointer.
Static members are not virtual, so you can not override them.
When you call DerivedClass.DoubleNumber you are actually calling BaseClass.DoubleNumber as the DerivedClass class doesn't have that method. Also, the use of MyNumber in that method is always going to be BaseClass.MyNumber no matter how you call the method.
What you are looking for is a virtual property that you can override in a derived class. As a virtual member can not be static, you need to use an instance of the class. If it's not practical to keep a reference to the instance, you can use the singleton pattern.
This kinda works:
public class ClassA
{
protected static int num = 5;
public static int GetNum()
{
return num;
}
}
public class ClassB : ClassA
{
static ClassB()
{
num = 6;
}
}
However, note the difference when you call ClassB.GetNum() before and after instantiating one object. The static initializer doesn't run until you create at least one, so you'll get 5 if nothing has been created, and 6 if at least one object has.
Provide a virtual method that returns the class static.
class BaseClass
{
public virtual int GetMyNumber() { return MyNumber; }
}
You might want to use a virtual property instead...
Using too much of static members is also not recommended if they are going to encapsulate a logic of an entire object. For example your code can be rewritten correctly in following manner... and this is the most recommended in oops,
class Program
{
static void Main(string[] args)
{
int Result = DerivedClass.Instance.DoubleNumber();
Console.WriteLine(Result.ToString()); // Returns 0
}
}
class BaseClass
{
protected BaseClass(){} // this enforces that it can not be created
public int MyNumber;
public virtual int DoubleNumber()
{
return (MyNumber*2);
}
}
public class DerivedClass : BaseClass
{
// this also ensures that it can not be created outside
protected DerivedClass(){
MyNumber = 5;
}
// only way to access this is by Instance member...
public static DerivedClass Instance = new DerivedClass();
}
This is how we access configuration values and many other single instance static objects provided by .Net Library.

Categories

Resources