[英]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.