C# 通过在不进行类型检查的情况下对其父级进行操作来填充 ObjectB 字段
C# Populate ObjectB field by operating on its parent without type checking
对象 X 有一些对象 B 感兴趣的数据,但它在其父对象(对象 A)上运行。对象 B 声明了一个未在对象 A 中声明的字段。对象 C 也是对象 A 的子对象,但它没有声明对象 B 所声明的字段。
如何填充对象 B 字段? (类型检查和转换真的是唯一的解决方案吗?)
编辑(添加了示例)
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
}
}
}
我可以在这里看到几个解决方案:
1:只有ObjectX
知道时间
如果time
只有ObjectX
可能知道,那么你可以将ObjectX
作为参数传递给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:可以在整个解决方案范围内知道时间:
如果时间只是一般时间而不是特定于 ObjectX
然后通过它自己的类型公开它 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'.
}
}
对象 X 有一些对象 B 感兴趣的数据,但它在其父对象(对象 A)上运行。对象 B 声明了一个未在对象 A 中声明的字段。对象 C 也是对象 A 的子对象,但它没有声明对象 B 所声明的字段。
如何填充对象 B 字段? (类型检查和转换真的是唯一的解决方案吗?)
编辑(添加了示例)
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
}
}
}
我可以在这里看到几个解决方案:
1:只有ObjectX
知道时间
如果time
只有ObjectX
可能知道,那么你可以将ObjectX
作为参数传递给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:可以在整个解决方案范围内知道时间:
如果时间只是一般时间而不是特定于 ObjectX
然后通过它自己的类型公开它 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'.
}
}