[英]Avoid casting when accessing base class properties from a derived class
作为C#的新手,我正竭尽全力地围绕用自己的方案进行铸造的最佳解决方案,基本上,我试图避免从派生类中铸造基类对象。
在我的GridManagerBase类中的示例中,GridTarget属性是由通用定义定义的,但是SelectedTarget使用的是基本接口,从GridManager类中继承该基本接口要求我强制转换以获得对其他属性的访问权限。
因此,我试图在不进行强制转换的情况下制定出一个干净的解决方案。
我在网上搜索了许多示例,但无法完全找到所需的答案,因此,确实需要任何建议。
非常感谢。
public class GridManager : GridManagerBase<IGridPoint>
{
void DoWork()
{
var result = GridTarget.HasVehicle; // works
var result2 = ((ITargetObject)SelectedTarget).SomeValue; // works with cast
}
}
public abstract class GridManagerBase<TGridPoint> : IGridManagerBase<TGridPoint>
where TGridPoint : class, IGridPointBase
{
public TGridPoint GridTarget { get; protected set; }
public ITargetObjectBase SelectedTarget { get; protected set; }
//public IVehicleObjectBase SelectedVehicle { get; protected set; }
}
public interface IGridManagerBase<TGridPoint>
{
TGridPoint GridTarget { get; }
ITargetObjectBase SelectedTarget { get; }
}
public interface IGridPointBase
{
int Row { get; }
}
public interface IGridPoint : IGridPointBase
{
bool HasVehicle { get; }
}
public interface ITargetObjectBase
{
int Row { get; set; }
}
public interface ITargetObject : ITargetObjectBase
{
int SomeValue { get; }
}
更新好的,所以我的主要目标是拥有一个以上的GridManager,其他对象具有该GridManager的共同功能,因此我的想法是使用基本接口来实现这一目标。
从GridManager中,SelectedTarget(ITargetObjectBase)对象将具有通用逻辑,这很好,但是在GridManager中也具有唯一逻辑。
在问这个问题之前,我确实考虑过Prasanna建议的路线,应该提到这一点,这就是为什么我在IVehicleObjectBase中添加了注释,但是我不确定用于创建几个通用定义的指导原则。
我在具体的类中添加了一些其他代码,希望可以更好地了解我所从事的工作。
public class GridManager : GridManagerBase<IGridPoint>
{
public GridManager()
{
GridTarget = new GridPoint();
SelectedTarget = new TargetObject(1, 2);
}
public void DoWork()
{
var result = GridTarget.HasVehicle; // works
var result2 = ((ITargetObject)SelectedTarget).SomeValue; // works with cast
SelectedTarget.DoSomeCommonWork();
}
}
public class GridManagerB : GridManagerBase<IGridPoint>
{
public GridManagerB()
{
GridTarget = new GridPoint();
SelectedTarget = new TargetObjectB(1, string.Empty);
}
public void DoWork()
{
var result = GridTarget.HasVehicle; // works
var result2 = ((ITargetObjectB)SelectedTarget).SomeOtherValue; // works with cast
SelectedTarget.DoSomeCommonWork();
}
}
public abstract class GridManagerBase<TGridPoint> : IGridManagerBase<TGridPoint>
where TGridPoint : class, IGridPointBase
{
public TGridPoint GridTarget { get; protected set; }
public ITargetObjectBase SelectedTarget { get; protected set; }
//public IVehicleObjectBase SelectedVehicle { get; protected set; }
}
public interface IGridManagerBase<TGridPoint>
{
TGridPoint GridTarget { get; }
ITargetObjectBase SelectedTarget { get; }
}
public interface IGridPointBase
{
int Row { get; }
}
public interface IGridPoint : IGridPointBase
{
bool HasVehicle { get; }
}
public interface ITargetObjectBase
{
int Row { get; set; }
void DoSomeCommonWork();
}
public interface ITargetObject : ITargetObjectBase
{
int SomeValue { get; }
}
public interface ITargetObjectB : ITargetObjectBase
{
string SomeOtherValue { get; }
}
public abstract class TargetObjectBase : ITargetObjectBase
{
public int Row { get; set; }
public TargetObjectBase(int row)
{
Row = row;
}
public void DoSomeCommonWork()
{
Console.WriteLine(Row.ToString());
}
}
public class TargetObject : TargetObjectBase, ITargetObject
{
public int SomeValue { get; private set; }
public TargetObject(int row, int some)
: base(row)
{
SomeValue = some;
}
}
public class TargetObjectB : TargetObjectBase, ITargetObjectB
{
public string SomeOtherValue { get; private set; }
public TargetObjectB(int row, string other)
: base(row)
{
SomeOtherValue = other;
}
}
public class GridPoint : IGridPoint
{
public int Row { get; set; }
public bool HasVehicle { get; set; }
}
因此,我认为我最好的两个选择要么是走通用定义路线,要么是从GridManagerBase删除ITargetObjectBase属性,而在IGridManager接口中只有ITargetObject。
GridTarget
不需要GridTarget
类型IGridPoint
的原因是:它是IGridPoint
类型,直接包含HasVehicle
的定义。 SelectedTarget
的类型为ITargetObjectBase
。 ITargetObjectBase
不直接包含了定义SomeValue
。 因此,需要ITargetObject
为ITargetObject
。 SelectedTarget.Row
中ITargetObjectBase
,因为ITargetObjectBase
包含Row
定义。 在您的情况下,可以将IGridManagerBase
为具有两个通用参数的类型,如下所示。 然后您可以在不进行强制转换的情况下调用SelectedTarget.SomeValue
public class GridManager : GridManagerBase<IGridPointA, ITargetObject>
{
void DoWork()
{
var result = GridTarget.HasVehicle; // works
var result2 = SelectedTarget.SomeValue; // works with cast
}
}
public abstract class GridManagerBase<TGridPoint, TTargetObject> : IGridManagerBase<TGridPoint,TTargetObject>
where TGridPoint : class, IGridPointBase
where TTargetObject : class, ITargetObjectBase
{
public TGridPoint GridTarget { get; protected set; }
public TTargetObject SelectedTarget { get; protected set; }
//public IVehicleObjectBase SelectedVehicle { get; protected set; }
}
public interface IGridManagerBase<TGridPoint, TTargetObject>
{
TGridPoint GridTarget { get; }
TTargetObject SelectedTarget { get; }
}
public interface IGridPointBase
{
int Row { get; }
}
public interface IGridPoint : IGridPointBase
{
bool HasVehicle { get; }
}
public interface IGridPointA : IGridPointBase
{
bool HasVehicle111 { get; }
}
public interface ITargetObjectBase
{
int Row { get; set; }
}
public interface ITargetObject : ITargetObjectBase
{
int SomeValue { get; }
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.