I have a few classes and I am having problems accessing properties defined in subclasses from other class methods.
I have a base class called Section
and a few subclasses, e.g. SectionPlane : Section
. In each subclass, a different set of fields and properties are defined (in SectionPlane
, private field _t
and public property t
can be found, whereas in SectionExtruded : Section
I have private field _A
and public property ´A´).
Class Section
// General section object
public abstract class Section
{
public Section()
{}
}
Class Plane Section
// Section object representing a plane with thickness t
public class SectionPlane : Section
{
private double _t;
public SectionPlane(double t)
{
this.t = t;
}
public double t
{
get
{
return _t;
}
set
{
_t = value;
}
}
}
Class Extruded Section
// Section object of some geometry with cross section area A extruded along the element it is assigned to.
public class SectionExtruded : Section
{
private double _A;
public SectionExtruded(double A)
{
this.A = A;
}
public double A
{
get
{
return _A;
}
set
{
_A = value;
}
}
}
The problem occurs when I from any subclass of the class Element
tries to access the properties, since theese are not set in the base class Section
, e.g. in the element Solid2D : Element
:
Class Element
public abstract class Element
{
private Section _section;
public Element(Section section)
{
this.section = section;
}
public Section section
{
get
{
return _section;
}
set
{
_section = value;
}
}
}
}
Class Solid 2D Element
// Solid2D elements can only have sections of type SectionPlane
public class Solid2D : Element
{
public Solid2D(SectionPlane section)
: base(section)
{
}
public void Calc()
{
double t = section.t; // This results in error 'Section' does not contain a definition for 't' and no extension method 't' accepting a first argument of type 'Section' could be found (are you missing a using directive or an assembly reference?)
}
}
Bar Element
// Bar elements can only have sections of type SectionExtruded
public class Solid2D : Element
{
public Solid2D(SectionExtruded section)
: base(section)
{
}
public void Calc()
{
double A = section.A; // This results in error 'Section' does not contain a definition for 'A' and no extension method 'A' accepting a first argument of type 'Section' could be found (are you missing a using directive or an assembly reference?)
}
}
Is there any way to access my property t
without having to include it in the base class Section
? This would be very helpfull since not all of the sections that I will use have the same properties.
Since you know that it can only be a SectionPlane
you can cast it
double t = ((SectionPlane)section).t;
If you are not sure whether you have a section of the right type, you can use the as
keyword
double t = 0;
var sectionPane = section as SectionPlane;
if (sectionPane != null) {
t = sectionPane.t;
}
as
does not throw an exception if the section has another type, but returns null
instead.
Or you can simply test
double t = 0;
if(section is SectionPlane) {
t = ((SectionPlane)section).t;
}
but this is less elegant than using as
, since you have to test the type and then cast it; but casting does this test again internally.
Using the new pattern matching introduced in C# 7.0 you can write:
double t = 0;
if(section is SectionPlane sp) {
t = sp.t;
}
But if you have to perfrom such a test, the question is, whether your approach is right in the object-oriented sense. If you move the Calc
-method to the abstract class Section
and let each class perform its own calculation, then no type test or casting will be required.
In Section
:
public abstract void Calc();
In SectionPlane
public override void Calc()
{
var x = t;
}
...
section.Calc(); // No casting or type test required.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With