【发布时间】:2016-09-27 04:18:04
【问题描述】:
作为 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 中,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 属性,然后将 ITargetObject 放在 IGridManager 接口中。
【问题讨论】:
-
几乎唯一的方法就是把它变成一个泛型。有理由不这样做吗?
-
不清楚你想用代码实现什么。
-
同意@ShaunLuttin,请提供一个包括演员表的当前用法示例,以及没有演员表的所需用法。