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

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();
}
}

Related

How to implement chat commands as separate classes?

I am currently working on the chatbot for the Twitch channel and would like to have all the commands to be separate classes in the program so that I will only need to add or remove a single class to add or remove command.
I've searched through the Internet for quite long but never came across the suitable design. Below is what I think it has to look like but can't find the proper syntax.
class Command()
{
string keyword;
int globalCooldown;
List<string> args;
}
class DoStuffA : Command(List<string> _args)
{
keyword = "pleasedostuffa";
globalCooldown = 2;
args = _args;
DoStuff(List<string> args)
{
//doing stuff A here with all the logic and so on
}
}
class DoStuffB : Command(List<string> _args)
{
keyword = "pleasedostuffb";
globalCooldown = 8;
args = _args;
DoStuff(List<string> args)
{
//doing stuff B here with all the logic and so on
}
}
Why do I need this is because I want to store all possible commands in the List<Commands> and when the new chat message appears, search which object of this list matches the keyword with the chat command and execute the appropriate function. For example, if someone posts !pleasedostuffa, I perform
foreach (Command c in commands)//commands is List<Command>
{
if(c.keyword==receivedCommand.command)//.command is string
{
c.DoStuff(receivedCommand.argsAsList)//.argsAsList is List<string>
}
}
I hope I explained this properly and really am eager to have at least a clue on how could this implemented.
Thank you in advance!
You have the method setup almost right, though there are a few other changes you need. You need to have the base class expose DoStuff() as a virtual method. Try this:
public abstract class Command
{
public string keyword;
public int globalCooldown;
//List<string> args;
public abstract void DoStuff(List<string> args);
}
public class DoStuffA : Command
{
//public string keyword = "pleasedostuffa";
//public int globalCooldown = 2;
//args = _args;
public DoStuffA()
{
keyword = "pleasedostuffa";
globalCooldown = 2;
}
public override void DoStuff(List<string> args)
{
//doing stuff A here with all the logic and so on
}
}
public class DoStuffB : Command
{
//public string keyword = "pleasedostuffb";
//public int globalCooldown = 8;
// args = _args;
public DoStuffB()
{
keyword = "pleasedostuffb";
globalCooldown = 8;
}
public override void DoStuff(List<string> args)
{
//doing stuff B here with all the logic and so on
}
}
So, a couple of notes.
Method inheritance
Here I make the base class abstract, simply to enforce that each and every child command implements the abstract function DoStuff(). After all, what would you do with an instance of the base class? It wouldn't do anything, because you don't have an actual implementation. So abstract helps both to avoid accidentally instantiating Command itself and also makes sure sub-type implementers do the right thing.
Second, at the child class level, you need to override the method on the base class. This ensures that anything calling ((Command)doStuffB).DoStuff() gets the proper implementation of the function.
Now that you have a DoStuff() method on Command, your foreach loop should work as you expect. You have the method available on the base class, so the virtual overrides at the child level can be run without casting.
Base class member access
The fields you are trying to declare here, keyword and globalCooldown, aren't how people would typically expose information like this, but before we get to that I'm going to explain the more fundamental principle of accessing base-class members from the inherited classes.
These two fields need to be marked public (and given a proper type) so that they can be used from outside the class (in your foreach). The public keyword is called an accessibility modifier, and there are a few other options for accessibility, but in your case only public is likely to do what you want.
As you can see, I've commented out the fields in the child classes. If you declare them there, they will hide (but not override) the members of the same name on the base class. There's no equivalent of virtual or abstract for fields, so you need another strategy. Here, we leave your original declaration of those fields on the base class so that they are available to anything holding any type of a Command. But instead of redeclaring them at the child class level, we simply set the values of the base class members in the constructor for the child classes.
Note that for clarity's sake, you could explicitly specify that you are setting a member on the base class by using base.keyword = "etc"; instead.
Exposing internal values via properties
As I noted, this will work, but it's not quite how most people would expose the keyword and globalCooldown values. For this, you'd typically use a property instead. This lets you store and expose the values without risking letting someone change the value (intentionally or unintentionally). In this case, you'd want to declare the property this way:
public string Keyword // properties start with a capital letter by convention
{
get; // The get accessor is public, same as the overall property
protected set; // the set accessor is protected
}
The protected set accessor means that this is still accessible to be set by the child classes, but not by anyone else. This is probably what you want. So now, in your child constructor, you can set base.Keyword = "whatever"; and your foreach code can reference, but not overwrite, that value. You can declare GlobalCooldown in a similar way.

Static Field Life Time in Base class

I have simple base class with single static field. I have numerous classes that derive from this base class. When I create a derived class, it causes invocation of the base classes static ctor which initializes the static field (Works as expected). The problem is that when I create another derived class, that inherits from same base, the static field in the base is still null, why???? It was initialized by the first class I instantiated.
Should not static fields in base classes have global allocation and be visible (ie. shared) to all derived classes?
My model:
class Base<T>
{
protected static object s_field = null;
static Base { s_field = new object(); }
}
class Derived1<T> : Base<T>
{
}
class Derived2<T> : Base<T>
{
}
// ... later in the program
Derived1<int> instance1 = new Derived1<int>(); // initializes static field (s_field in base class) for all derived types
Derived2<double> instance2 = new Derived2<double>(); // the static field is null
(I can see this through the debugger, but should it not already have been initialized by previous line??)
Since you have changed your code i believe you need to understand how generics works in .NET.
Static in generics behaves a bit different than in normal cases. For each unique open type T you provide, the base class maintains unique static member value.
You create another instance of open type double for the same base class via Derived < double > then youll see the concept what i am talking about.
Here a sample code to demonstrate more clearly :
public class Base<T>
{
public static string str = null;
static Base()
{
str = "hello";
Console.WriteLine("Ctor cald");
}
}
public class Derived1<T> : Base<T>{}
public class Derived2<T> : Base<T> { }
public partial class Program
{
public static void Main()
{
Derived1<int> derv = new Derived1<int>();
Derived2<double> derv2 = new Derived2<double>();
Derived2<double> derv3 = new Derived2<double>();
Console.ReadKey();
}
}
Here you shall see only 2 calls for the static Ctor.
I realized my mistake! Wow, the base class is actually a template class: Base<T>. When I create object of the base like this new Derived<int>(), new Derived<double>(), new Derived<object>(), these are completely different types and therefore the static field rules are different, my understanding is that the static field will be allocated for family of type T.
I have corrected the example above to reflect this (in the initial post).
Whole question changes when you put generics into the picture. Your understanding on inheritance of static members works as expected without generics and when Generics are in places, still the concept is valid with the exception that, Generics creates different types at run time.
Base<int> and Derived1<int> share the same static member where as Derived1<decimal> would be a different type than Base<int> at run time which doesn't share the static member with.

can we access a private variable using an object

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();
}
}
}

C# sample syntax question

Please, help me with to understand this piece of code:
protected Customer()
{
}
in the following class (Model class from sample WPF MVVM app):
public class Customer : IDataErrorInfo
{
#region Creation
public static Customer CreateNewCustomer()
{
return new Customer();
}
public static Customer CreateCustomer(
double totalSales,
string firstName,
string lastName,
bool isCompany,
string email)
{
return new Customer
{
TotalSales = totalSales,
FirstName = firstName,
LastName = lastName,
IsCompany = isCompany,
Email = email
};
}
protected Customer() // it is what I asked about
{
}
#endregion // Creation
......
}
protected Customer() { } is a constructor, a special method that automatically gets called when you instantiate an object from a class. When you type Customer c = new Customer(), the constructor is allowed to initialize that instance after the run-time has allocated and reset memory for it. The protected keyword means that only code inside the class Customer or of its descendants are allowed to instantiate said class using that specific constructor.
The piece of code you point at is a constructor. It is a method that (potentially) gets automatically invoked whenever an instance of your class is created at runtime.
In this case, it is marked with the protected keyword. This means that only the owner class plus any derived classes (i.e. classes that inherit from it) have access to it.
By looking at your code, the two versions of the CreateNewCustomer() static method in your class create instances of the class, invoking the constuctor. By making the constructor protected, the code guarantees that the class retains exclusive control over instantiation; this means that no other code outside the class (or its descendant classes) can create instances of this class.
The constructor is protected so that only the static creation methods can actually instantiate the class.
This means that the constructor for your class has "protected" access, meaning that only members of this class or subclasses can call it. Practically, this means that either a static method is being used to create an instance of this class, or that another constructor (possibly in a derived class) is delegating to this constructor.
Using the protected keyword on the constructor only allows instantiation of the Customer object inside itself (like the static factory methods) and inside any class that derives from Customer.

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