Object X has some data that Object B is interested in but it operates on its parent (Object A). Object B declares a field that isn't declared in object A. Object C is also a child of Object A but it doesn't declare that field that object B does.
How to populate object B field? (is type checking and casting really the only solution?)
EDIT (Added an example)
public class ObjectX
{
// eventually interested by ObjectB
public float time;
private ObjectA _objectAOrBStoredInAReference;
public ObjectX(ObjectA objectAOrB)
{
this._objectAOrBStoredInAReference = objectAOrB;
}
public void PassTimeToObjectB()
{
// need to pass the time to ObjectB since it is interested in this
}
public void SomeStuffToDo()
{
PassTimeToObjectB();
_objectAOrBStoredInAReference.StuffToDo();
}
public abstract class ObjectA
{
public abstract void StuffToDo();
}
public class ObjectB : ObjectA
{
public float time;
public void SetTime(float time)
{
this.time = time;
}
public override void StuffToDo()
{
// Using Populated time here
}
}
}
CodePudding user response:
I can see a couple of solutions here:
1: Only ObjectX
knows the time
If the time
is such that only ObjectX
can possibly know it, then you can pass ObjectX
as an argument to StuffToDo
:
public class ObjectX
{
// eventually interested by ObjectB
private float time;
// Expose 'time' as a readonly property - I'm assuming
// other classes shouldn't need to manipulate it?
public float Time => time;
private ObjectA _objectAOrBStoredInAReference;
public ObjectX(ObjectA objectAOrB)
{
this._objectAOrBStoredInAReference = objectAOrB;
}
public void SomeStuffToDo()
{
// Don't need to set the time anymore -
// ObjectB can retrieve the time itself.
_objectAOrBStoredInAReference.StuffToDo(this);
}
}
public class ObjectB : ObjectA
{
// REMOVE ALL THIS CODE - NOT NEEDED ANYMORE
//public float time;
//public void SetTime(float time)
//{
// this.time = time;
//}
public override void StuffToDo(ObjectX x)
{
var time = x.Time;
// Do stuff involving 'time'.
}
}
2: The time can be known solution-wide:
If the time is just a general time that is not specific to ObjectX
then expose it via it's own type ITimeProvider
:
public interface ITimeProvider
{
float Time { get;}
}
public class ObjectX
{
// Remove any 'time' related stuff from X
private ObjectA _objectAOrBStoredInAReference;
public ObjectX(ObjectA objectAOrB)
{
this._objectAOrBStoredInAReference = objectAOrB;
}
public void SomeStuffToDo()
{
_objectAOrBStoredInAReference.StuffToDo();
}
}
public class ObjectB : ObjectA
{
private readonly ITimeProvider _timeProvider;
public ObjectB(ITimeProvider timeProvider)
{
this._timeProvider = timeProvider;
}
public override void StuffToDo(ObjectX x)
{
var time = _timeProvider.Time;
// Do stuff involving 'time'.
}
}