c# - Calling item methods on an array of different types -
my task simple: have create dynamic array (which means size can change during runtime) , fill (depends on user input, in runtime) objects of different types. moreover, should possible me access fields (and/or methods) of every object in array. obviously, fields different each type. simplified structure:
public class point {} public class righttriangle:point { public double sidea, sideb; } public class circle:point { public double radius; } public class cone:circle { public double radius, height; }
so, see: classes inherit 1 base class. , know, these structure kind of illogical, that's not choice. so, want code work:
righttriangle rt1 = new righttriangle(); cone cn1 = new cone(); list<point> objs = new list<point>(); objs.add(rt1); sidea_tb.text = objs[0].sidea.tostring();
but doesn't. compiler says there no sidea
in point
. not work either:
public class point { public double sidea, sideb, radius, height; } public class righttriangle:point { public new double sidea, sideb; } public class circle:point { public new double radius; } public class cone:circle { public new double radius, height; }
it seems values actual class (rt1
, righttriangle
) not override ones in point
class, i've got this:
list<point> objs = new list<point>(); objs.add(rt1); // rt1 has fields 'sidea' = 4, 'sideb' = 5 sidea_tb.text = rt1.sidea.tostring(); // got 4, okay sidea_tb.text = objs[0].sidea.tostring(); // got 0, the?
so, basically, need dynamic array of links, , want use links access objects fields , methods. also, know can write get/set
functions in base class , override them in child classes, not seems beauty solution. in advance , please forget illiteracy (english isn't native).
you had (in theory):
public class point { public virtual double sidea, sideb, radius, height; } public class righttriangle:point { public override double sidea, sideb; }
to make properties , methods overridable in derived classes have declared virtual
in base class. overriding class has declare overriden property/method override
.
in practice cannot make fields virtual
, properties , methods can be. have change code follows:
public class point { public virtual double sidea { get; set; } public virtual double sideb { get; set; } public virtual double radius { get; set; } public virtual double height { get; set; } } public class righttriangle:point { public override double sidea { get; set; } public override double sideb { get; set; } }
however, should not bad design. more below.
so what's difference new
?
when method overriden decided at runtime whether overridden or original implementation called.
so when method receives point
argument, point
instance might righttriangle
or circle
.
point p1 = new righttriangle(); point p2 = new circle();
in above example, both p1
, p2
point
s perspective of code uses p1
, p2
. however, "underneath" instances of derived classes.
so solution, when acess p1.sidea
example, the runtime "underneath" , check point
is: righttriangle
? check if there overridden implmentation of sidea
, call one. circle
? same check (which fail) , call original implmentation of sidea
.
the new
qualifier else. not override method, create new 1 (with same name), handled differently at compile time.
so solution, compiler sees created righttriangle
, stored in variable of type point
. when access p1.sidea
example, compiler compile access in such way reads sidea
base class, since instance variable dealing has base type.
if still want access new
implementation, code using p1
has cast correct derived type righttriangle
:
var w = ((righttriangle)p1).sidea; // gets correct value.
so what's problem?
as may have noticed now, using new
not solution. code uses kinds of point
s has know whether specific derivate of point
implements field new
or not. has know, when receives point
instance kind of instance acutally underneath. lead lots of elaborate if
-else
statements check kind of point p1
being dealt , run appropriate behvaiour.
using virtual
, override
alleviates last problem, if base class implements all methods , properties derived class implements. kind of insane. tried , i'm sure noticed on way doesn't make sense give point
sidea
, sideb
and radius
. how point
ever implement properties meaningfully? , cannot make them abstract
either, because circle
had implement sidea
, on.
so how solve in better way?
think want whith differnet point instances. collect them in list reason: have in common. iterate on list doing each 1 of them specific reason well. trying exactly? can describe in abstract way?
maybe getting side lengths , radiuses calculate area? give point
virtual
method getarea()
, override in each derived class. method getarea()
makes sense on derived types, although implemented differently in each 1 of them.
you make getarea()
abstract
method instead of virtual
one. means not implemented in base class @ , derived types forced implement on own.
maybe don't want handle point
s in list righttriangle
s only? code doing should receive righttriangle
s:
public void handlerighttriangles(ienumerable<righttriangle> rts) { // can work sidea , sideb directly here, because know got triangles. }
call with:
// using system.linq; handlerighttriangles(objs.oftype<righttriangle>());
Comments
Post a Comment