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
SectionPlaneyou can cast itIf you are not sure whether you have a section of the right type, you can use the
askeywordasdoes not throw an exception if the section has another type, but returnsnullinstead.Or you can simply test
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:
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 classSectionand let each class perform its own calculation, then no type test or casting will be required.In
Section:In
SectionPlane