C# 转换为抽象泛型基类
我有一个从Mvc控制器继承的抽象泛型类使用泛型类型创建项目字典,类似于:C# 转换为抽象泛型基类,c#,generics,casting,abstract-class,C#,Generics,Casting,Abstract Class,我有一个从Mvc控制器继承的抽象泛型类使用泛型类型创建项目字典,类似于: public abstract class BaseController<TElement> : Controller where TElement : BaseElement { public Dictionary<string, TElement> Stuff { get; set; } string Name; public BaseController()
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>;
}
}
公共抽象类BaseController:Controller,其中TElement:BaseElement
{
公共字典内容{get;set;}
字符串名;
公共BaseController()
{
this.Name=Helper.GetName();
this.Stuff=Helper.GetStuff(Name)作为字典;
}
}
然后,我有几个不同的BaseControllers实现,它们根据命名对象的标准传入不同类型的BaseElement(我相信这一部分是不相关的,但请告诉我它是否影响了我的最终结果)
问题是,稍后我需要从actionfilter检查“Stuff”属性是否为null,actionfilter通过基本Mvc控制器属性访问BaseController的实例
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var controller = filterContext.Controller as **BaseWidgetController**; // <-- here
if (controller == null)
throw new Exception(filterContext.Controller.GetType().ToString());
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var controller=filterContext.controller as**BaseWidgetController**;//很难编写从基类到泛型派生类之一的强类型代码。一个选项是使用动态
而不是强类型代码
另一种选择是使用非泛型基类或接口,除非您需要使用特定类型的元素:
interface IHasTheStuff
{
bool HaveStuff();
}
public abstract class BaseController<TElement> : IHasTheStuff, Controller ...
{
...
public bool HaveStuff() { return Stuff != null;}
}
也许我有点慢。如果Thing
继承自BaseThing
,它是否已经具有Stuff
属性?我也是这么想的。除非childing
类中的一个覆盖或隐藏它(以某种方式更改功能),那么如果它进入null
,那么它实际上可能只是null
。另外,它是Helper.GetStuff(Name)
实际返回某些内容?如果它返回某些内容,您是否100%确定它的类型为字典
?如果不是,则as
操作符将在构造函数中默认此项。将填充为null
。实际上,我想我可能没有正确解释这一点,因为我试图将其设置为通用的有可能避免事情复杂化。这是在MVC环境下,让我更新它以更好地解释我试图做什么derviedOrBase.Stuff!=null
,或者我遗漏了什么?你能发布你试图在无法访问Stuff
的地方工作的代码吗?@Josh-关于动态/反射-查看Eric Lippert的回答:。我喜欢使用基类/接口的静态类型路由。使用该接口非常完美,并允许我将其强制转换到该接口而不会出现任何问题,感谢这看起来像一个技巧!@josh我的内部技巧是避免感觉像C
和C
这样的两个泛型与inheritan有共同之处ce观点(如果你有一些共同的基础C类:基础,这一点尤其诱人)-事实上,它们只与两个独立的类相关。如果您将它们想象为类C_T1:Base
和类C_T2:Base
,您可能会更好地理解什么类型的强制转换是有意义的,什么是没有意义的。顺便说一句,在您的情况下,差异可能不起作用。对于像MVC控制器这样涉及的代码,您通常需要完整的类型(因为差异需要接口类型)或者,即使您设法限制自己使用接口,您最终也需要在类型参数上同时使用in
和out
。非常感谢您提供了额外的见解,我认为在这种情况下,它足够简单,但我相信这会反复出现
Controller justController...
if (((IHasTheStuff)justController).HaveStuff())...