当您具有抽象类型的数组时,如何访问不在抽象类型上的派生类型成员

凯尔·理查森(Kyle Richardson)

请查看以下代码块,以给出遵循适当上下文的问题。

抽象类

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));

现在,由于List < Asset>声明的,Asset does not contain a definition for Controller当我尝试访问时得到一个Assets[0].Controller

在C#中获得这种动态功能的惯用方法是什么?我需要能够在集合中存储不同的特定类型并对其非派生成员进行操作。我是来自JavaScript领域的新鲜人,这里的狗可以是猫,因此任何帮助将不胜感激。

技术咨询

简单的转换可能很有用,但不适用于许多应用程序。我建议一起采取其他方法。如何使用泛型让实现类处理属性类型(并将该属性保留在基类中以供所有人使用)。

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
    }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章