简体   繁体   中英

C# cast non-generic class to generic base class regardless of type T

We want to convert a List<Rule> where we know they all derive from BuildingRule<T> into BuildingRule<T> , but the type T can be different.
We basically want to do _buildingRules.Find(x => ((BuildingRule<T>)x).GetBuilding(sku, upgradeId) != null)
(the `.GetBuilding().= null is a requirement the rule has to meet in order for it to be the right one).

Though this does not work, and we were wondering if there is a way to achieve what we are trying to do.

public abstract class Rule
{
    [XmlIgnore]
    public abstract string FileName { get; }
}

public abstract class BuildingRule<T> : Rule where T : BuildingDefinitionRule
{
    [XmlElement("Definition")]
    public virtual List<T> Definitions { get; set; }

    public virtual T GetBuilding(string sku, int upgradeId = 0)
    {
        return Definitions.Find(x => x.Sku == sku && x.UpgradeId == upgradeId);
    }
}

public abstract class BuildingRule : BuildingRule<BuildingDefinitionRule>
{
}```

You can create non-generic BuildingRuleBase :

public abstract class BuildingRuleBase : Rule
{
    public abstract BuildingDefinitionRule GetBuilding(string sku, int upgradeId = 0);
}

And inherit it:

public abstract class BuildingRule<T> : BuildingRuleBase where T : BuildingDefinitionRule
{
    public override T GetBuilding(string sku, int upgradeId = 0)
    {
        return Definitions.Find(x => true);
    }
}

And make _buildingRules a collection of BuildingRuleBase .

Or look into using covariant generic interfaces:

public interface IBuildingRule<out T> where T : BuildingDefinitionRule
{
    T GetBuilding(string sku, int upgradeId = 0);
}

public abstract class BuildingRule<T> : Rule, IBuildingRule<T> where T : BuildingDefinitionRule
{
    [XmlElement("Definition")]
    public virtual List<T> Definitions { get; set; }

    public T GetBuilding(string sku, int upgradeId = 0)
    {
        return Definitions.Find(x =>true);
    }
}

With new List<IBuildingRule<BuildingDefinitionRule>>() for type of _buildingRules .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM