Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

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

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

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.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading