请查看以下代码块,以提供符合正确背景的问题。
抽象类:
public abstract class Asset
{
public GameObject Mode { get; set; }
public AssetDimensions Dimensions { get; set; }
public string BundleName { get; set; }
public string ModelName { get; set; }
public virtual string Type { get; }
public string Sku
{
get
{
return this._sku;
}
}
private string _sku;
public Asset(AssetConfig assetConfig)
{
this.Model = null;
this.Dimensions = new AssetDimensions(assetConfig.dimensions);
this.BundleName = assetConfig.bundleName;
this.ModelName = assetConfig.modelName;
this._sku = assetConfig.sku;
}
}
派生类:
public class SpecificAsset : Asset
{
public SpecificAssetController Controller { get; set; }
public override string Type
{
get
{
return this._type;
}
}
private string _type;
public SpecificAsset(AssetConfig assetConfig) : base(assetConfig)
{
this._type = "SpecificAsset";
}
}
初始化列表< Asset
>并向其添加SpecificAsset
:
public List<Asset> Assets = new List<Asset>();
Assets.Add(new SpecificAsset(assetConfig));
现在因为列表&lt; Asset
&gt;声明我尝试访问Asset does not contain a definition for Controller
Assets[0].Controller
在C#中获得这种动态功能的惯用方法是什么?我需要能够在集合中存储不同的特定类型,并对其非派生成员进行操作。我是新鲜的JavaScript土地,狗可以是猫,所以任何帮助将不胜感激。
答案 0 :(得分:3)
简单的强制转换可能很有用,但对许多应用程序都没有用。我建议一起采取不同的方法。如何使用泛型让实现类处理属性类型(并将属性保留在基类中供所有人使用)。
public abstract class Asset<T> where T : IController
{
...
public T Controller { get; set; }
...
}
public interface IController
{
void ContollerMethod();
}
实现看起来像这样:
public class SpecificAsset : Asset<ControllerImpl>
{
....
}
public class ControllerImpl : IController
{
public void ControllerMethod()
{
//Some code here...
}
}
当您需要在基类中拥有一个或两个不同类型的属性时,此方法可以很好地工作。这允许类继承来定义它们将使用的类型。这不是每次都很好的方法(例如,如果你想让实现类定义3种以上的不同类型)。
编辑:我还会注意到这会使事情变得更容易的情况。请考虑以下代码:
public void TestMethod()
{
List<Asset<IController>> assets = new List<Asset<IController>>();
//Populate assets list here
foreach (Asset<IController> asset in assets)
{
asset.Controller.ControllerMethod();
//Here we cannot cast to a specific type easily because we may not know them at runtime.
//With the generic, we can still make any appropriate calls and not know the specifics
}
}
答案 1 :(得分:0)
试试((SpecificAsset)Assets[0]).Controller
。理想情况下,你会使用is and as casts以便获得某种安全性,但如果你确定它们总是来自Asset
,那么硬拼接就可以了。
您应该调查abstact classes,您可以创建一个BaseAsset
类,其中包含所有Asset
的公共属性,Asset
和SpecificAsset
也只会必须实现特定于它们的属性。至于列表的输入,它可以保持不变。