简体   繁体   中英

casting to an abstract generic base class

I have an abstract generic class that inherits from the Mvc Controller uses the generic type to create a dictionary of items, similar to this:

public abstract class BaseController<TElement> : Controller where TElement : BaseElement
{
    public Dictionary<string, TElement> Stuff { get; set; }
    string Name;

    public BaseController()
    {
        this.Name = Helper.GetName();
        this.Stuff = Helper.GetStuff(Name) as Dictionary<string, TElement>;
    }
}

I then have several different implementations of BaseControllers that pass in different types of BaseElement, based on a criteria that names the object (I believe this part is irrelevant, but please let me know if it's affecting my end result).

The problem is later I need to check if the "Stuff" property is null from an actionfilter, which accesses instances of BaseController through the base Mvc Controller property.

public override void OnActionExecuting(ActionExecutingContext filterContext)
{
    var controller = filterContext.Controller as **BaseWidgetController**; // <-- here
    if (controller == null)
        throw new Exception(filterContext.Controller.GetType().ToString());
}

My "BaseController" is a controller, so it does fit into that property, but I can't figure out how to cast it to my BaseController type to get the Stuff property...

Can this be done? I've seen while searching mention of covariance, but I can't seem to get my head around it, is that what I need to make this work?

I also saw using reflection as a solution but that is expensive and won't work for my particular situation.

finally I saw that this could work if I defined the base as an Interface instead of abstract class, but I need that base behavior as it will be shared across all inherited types...

The main reason I'm typing this question out is because SO always comes up with great similar questions and i usually just end up finding my answer, but this time I'm really lost with the covariance and generics, so I could use some insight as to whether or not this is even possible, or if I should be doing this in a completely different way...

It is hard to write strongly typed code that goes from base class to one of derived classes that are generic. One option is to use dynamic instead of strongly typed code.

Another option is to have non-generic base class or interface unless you need to work with elements of particular type:

interface IHasTheStuff
{
  bool HaveStuff();
}

public abstract class BaseController<TElement> : IHasTheStuff, Controller ...
{
   ...
   public bool HaveStuff() { return Stuff != null;}
}

And than when you have just controller cast to that interface:

Controller justController...
if (((IHasTheStuff)justController).HaveStuff())...

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