Lets say I have three classes, p, p1 and p2
public class p
{
public p() {}
}
public class p_1 : p
{
public p_1() {}
public string tester = "ABC";
}
public class p_2 : p
{
public p_2() {}
public string foo = "Test";
}
Now I want to create a general variable of the type p and then use it as type p_1. Then I want to access the variable tester inside.
p p_tester;
p_tester = new p_1();
Console.Writeline(p_1.tester);
My question is: Why can't I access the .tester variable? Am I missing something? Visual studio wants me to declare all variables from the subclasses in the main class... but that is not what I want.
Is that what I try to do even possible?
The only way I've found to do this is to cast p_tester as p_1.
The one thing I'm sure is that you can't access p_1 directly because your class is not static. You can only access the declared instance p_tester
p p_tester;
p_tester = new p_1();
Console.WriteLine(((p_1)p_tester).tester);
Your declare function is wrong. Why not access it through the child class?
p_1 p_tester;
p_tester = new p_1();
Console.WriteLine(p_tester.tester);
If you want to access the tester form child class p_1() then you could set the tester as static variable.
public class p_1 : p
{
public p_1() {}
public static string tester = "ABC";
}
Console.WriteLine(p_1.tester);
It seems you actually need an override property
public class p
{
public p() {}
public virtual string StringValue { get; }
}
public class p_1 : p
{
public p_1() {}
public string tester = "ABC";
public override string StringValue => tester;
}
public class p_2 : p
{
public p_2() {}
public string foo = "Test";
public override string StringValue => foo;
}
You can now access it using p_tester.StringValue
p p_tester = new p_1();
Console.Writeline(p_1.StringValue);
Related
I don't know how to define my question (probably already asked but didn't found it).
I want to create a constructor for a class B inherited from A taking a B object as parameter used to be a copy of it.
There can be something like this :
class B : A
{
public String NewField;
public B(A baseItem, String value)
{
// Create new B to be a copy of baseItem
???; // something like : this = baseItem
// Add new field
NewField = value;
}
}
Objective is to create an object B which is the exact copy of an A object with on filed more.
Use the base keyword to call the parent class constructor, giving your parent class instance as a parameter. Then create a copy constructor in your parent, and you're done.
class A
{
public A(A a)
{
// Copy your A class elements here
}
}
class B : A
{
public String NewField;
public B(A baseItem, String value)
: base(baseItem)
{
NewField = value;
}
}
You could implement a CopyProperties method, which will copy the properties values.
using System;
public class A
{
public string Filename {get; set;}
public virtual void CopyProperties(object copy)
{
((A)copy).Filename = this.Filename;
}
}
public class B : A
{
public int Number {get;set;}
public override void CopyProperties(object copy)
{
base.CopyProperties(copy);
((B)copy).Number = this.Number;
}
}
public class Program
{
public static void Main()
{
B b = new B { Filename = "readme.txt", Number = 42 };
B copy = new B();
b.CopyProperties(copy);
Console.WriteLine(copy.Filename);
Console.WriteLine(copy.Number);
}
}
I need the separate classes for Xml Serialization. I'd like to know if there is a simpler way for the inheriting BuildingDetail class to acquire the property values from the parent Building class.
Parent Class
public class Building
{
public int BuildingId;
public string BuildingName;
protected Building()
{
}
private Building(int buildingId, string buildingName)
{
BuildingId = buildingId;
BuildingName = buildingName;
}
public static Building Load(int buildingId)
{
var dr = //DataRow from Database
var building = new Building(
(int) dr["BuildingId"],
(string) dr["BuildingName"]);
return building;
}
}
Inheriting Class
public class BuildingDetail : Building
{
public BaseList<Room> RoomList
{
get { return Room.LoadList(BuildingId); }
}
protected BuildingDetail()
{
}
// Is there a cleaner way to do this?
private BuildingDetail(int buildingId, string buildingName)
{
BuildingId = buildingId;
BuildingName = buildingName;
}
public new static BuildingDetail Load(int buildingId)
{
var building = Building.Load(buildingId);
var buildingDetail = new BuildingDetail(
building.BuildingId,
building.BuildingName
);
return buildingDetail;
}
}
Thanks.
Firstly, change your base class constructor access modifier to protected. And then you can call base class constructor with base keyword:
private BuildingDetail(int buildingId, string buildingName)
: base(buildingId, buildingName)
{
...
}
It will call the base constructor first. Also if you don't put the :base(param1, param2) after your constructor, the base's empty constructor will be called.
Lets suppose we have these classes:
class A {
public string attr = "Class A";
public static void getAttribute(){
self currentClass = new self(); // equivalent to php
Console.Write("Attribute : " + currentClass.attr);
}
}
Class B : A {
public string attr = "Class B";
}
B = new B();
B.getAttribute();
I want B.getAttribute(); to print Attribute: Class B. How can I do this?
This is fundamentally impossible.
B.getAttribute() compiles to A.getAttribute().
I probably know what you are trying to do, but I have to tell you that this kind of PHP approach makes no sense in C#. I discourage you from using it.
public class A
{
private String attr = "Class A";
public static String getAttribute()
{
return (new A()).attr;
}
}
public class B : A
{
private String attr = "Class B";
public static String getAttribute()
{
return (new B()).attr;
}
}
You get the current class instance by the 'this' keyword. Obviously you cannot access that in a static method since by definition a static method executes without the context of a particular instance.
On the other hand, to access a member variable/property/method from inside the same class, you don't need the 'this' keyword at all, since it's implicit.
If you're asking how to do something like that in C#, I think the answer would be along these lines:
public class A
{
public virtual string attr
{
get { return "Class A" }
}
public void getAttribute(){
Console.Write("Attribute : " + attr);
}
}
public class B : A
{
public override string attr
{
get { return "Class B"; }
}
}
var b = new B();
b.getAttribute();
Regarding my comment in the other answer, if you needed getAttribute to be static, you could implement it this way:
public static void getAttribute(A obj){
Console.Write("Attribute : " + obj.attr);
}
You would then call it like this:
var b = new B();
A.getAttribute(b);
how do i acces the property value from an internal class , see below?
namespace N1
{
public class ClassA
{
string var1 = null;
private ClassB b;
public ClassA()
{
var1 = "one";
b = new ClassB();
}
//property
public string Var1
{
get{ return var1; }
}
}
namespace N1
{
internal class ClassB
{
private void method()
{
// I need to access the value of Var1( property) from here, how to do this?
}
}
}
Pass an instance of ClassA into ClassB's constructor:
namespace N1
{
internal class ClassB
{
private ClassA _classAInstance;
public void ClassB(ClassA classAInstance)
{
_classAInstance = classAInstance;
}
private void method()
{
// You can access _classAInstance properties here
}
}
}
Update: I missed that a ClassB instance b was a private member on ClassA. Using my previous answer, you can just instantiate b in ClassA's constructor:
public ClassA()
{
var1 = "one";
b = new ClassB(this);
}
You need a reference to an instance of Class A.
So either change Class B constructor to accept a reference to class A
namespace N1
{
public class ClassA
{
string var1 = null;
private ClassB b;
public ClassA()
{
var1 = "one";
b = new ClassB(this);
}
//property
public string Var1
{
get { return var1; }
}
}
}
namespace N1
{
internal class ClassB
{
ClassA classA;
public ClassB(ClassA classARef)
{
classA = classARef;
}
private void method()
{
// I need to access the value of Var1( property) from here, how to do this?
string myString = classA.Var1;
}
}
}
or make ClassB's private method() take in a string? private void method(string classAVar1)
or make ClassA static (haha)
Well there are a couple of ways:
Change the access modifier of ClassB.Method to be public and make it take a string parameter.
Update the constructor of ClassB to take a string parameter and store it in a private field.
Add a public string property to ClassB.
Making a class internal just means the class is only available with files inside the same assembly.
You can't. Change access modifiers of either class A or B.
Purpose of internal class is to contain some internal logic implementation, and if you have need to access public classes' fields from it, probabli something wrong with app design
Without any code in the subclasses, I'd like an abstract class to have a different copy of a static variable for each subclass. In C#
abstract class ClassA
{
static string theValue;
// just to demonstrate
public string GetValue()
{
return theValue;
}
...
}
class ClassB : ClassA { }
class ClassC : ClassA { }
and (for example):
(new ClassB()).GetValue(); // returns "Banana"
(new ClassC()).GetValue(); // returns "Coconut"
My current solution is this:
abstract class ClassA
{
static Dictionary<Type, string> theValue;
public string GetValue()
{
return theValue[this.GetType()];
}
...
}
While this works fine, I'm wondering if there's a more elegant or built-in way of doing this?
This is similar to Can I have different copies of a static variable for each different type of inheriting class, but I have no control over the subclasses
There is a more elegant way. You can exploit the fact that statics in a generic base class are different for each derived class of a different type
public abstract class BaseClass<T> where T : class
{
public static int x = 6;
public int MyProperty { get => x; set => x = value; }
}
For each child class, the static int x will be unique for each unique T
Lets derive two child classes, and we use the name of the child class as the generic T in the base class.
public class ChildA: BaseClass<ChildA>
{
}
public class ChildB : BaseClass<ChildB>
{
}
Now the static MyProperty is unique for both ChildA and ChildB
var TA = new ChildA();
TA.MyProperty = 8;
var TB = new ChildB();
TB.MyProperty = 4;
While this works fine, I'm wondering if there's a more elegant or built-in way of doing this?
There isn't really a built-in way of doing this, as you're kind of violating basic OO principles here. Your base class should have no knowledge of subclasses in traditional object oriented theory.
That being said, if you must do this, your implementation is probably about as good as you're going to get, unless you can add some other info to the subclasses directly. If you need to control this, and you can't change subclasses, this will probably be your best approach.
This is a little different than what you're asking for, but perhaps accomplishes the same thing.
class Program
{
static void Main(string[] args)
{
Console.WriteLine((new B()).theValue);
Console.WriteLine((new C()).theValue);
Console.ReadKey();
}
}
public abstract class A
{
public readonly string theValue;
protected A(string s)
{
theValue = s;
}
}
public class B : A
{
public B(): base("Banana")
{
}
}
public class C : A
{
public C(): base("Coconut")
{
}
}
There's an alternative solution which might or might not be better than yours, depending on the use case:
abstract class ClassA
{
private static class InternalClass<T> {
public static string Value;
}
public string GetValue()
{
return (string)typeof(InternalClass<>)
.MakeGenericType(GetType())
.GetField("Value", BindingFlags.Public | BindingFlags.Static)
.GetValue(null);
}
}
This approach is used in EqualityComparer<T>.Default. Of course, it's not used for this problem. You should really consider making GetValue abstract and override it in each derived class.
What about this?
class Base {
protected static SomeObjectType myVariable;
protected void doSomething()
{
Console.WriteLine( myVariable.SomeProperty );
}
}
class AAA : Base
{
static AAA()
{
myVariable = new SomeObjectType();
myVariable.SomeProperty = "A";
}
}
class BBB : Base
{
static BBB()
{
myVariable = new SomeObjectType();
myVariable.SomeProperty = "B";
}
}
It works for me.
Would be even nicer with Interface.
Simple solution: just use word "new".
public abstract class AbstractClass
{
public static int Variable;
}
public class RealizationA : AbstractClass
{
public new static int Variable;
}
public class RealizationB : AbstractClass
{
public new static int Variable;
}
And the result:
AbstractClass.Variable = 1;
RealizationA.Variable = 2;
RealizationB.Variable = 3;
Console.WriteLine(AbstractClass.Variable); //1
Console.WriteLine(RealizationA.Variable); //2
Console.WriteLine(RealizationB.Variable); //3
or you can use property:
//in abstract class
public static int Variable {get; set;}
//in child class
public static new int Variable {get; set;}
or function (but remember to add "new" to both variable and function):
//in abstract class
protected static int Variable;
public static int GetVariable() { return Variable; }
public static void SetVariable(int v) { Variable = v; }
//in child class
protected new static int Variable;
public static new int GetVariable() { return Variable; }
public static new void SetVariable(int v) { Variable = v; }
or you can use private variables (you don't need to use "new") with functions to get and set:
//in abstract class
private static int Variable;
//get and set methods
//in child class
private static int Variable;
//get and set methods