我喜欢在类中重写一个方法,所以我使用相同的名称和参数扩展该方法,但它永远不会被调用。
http://msdn.microsoft.com/en-us/library/bb383977.aspx
....永远不会调用与接口或类方法具有相同名称和签名的扩展方法。 ....
好的,我必须接受这个。
我的问题是: 对于未密封的类(甚至我有源代码),如果我想重写类的方法 OUTSide (在不同的项目中但是相同的解决方案),怎么做?
[编辑]
这是建议的方式,使用虚拟/覆盖,运行时没有错误,编译时没有错误,只是永远不会被调用:(,请看看
在项目A中:
public class CachePlan : ICachePlan
{
public virtual CacheSettings GetPlan(ControllerContext filterContext)
{
return null;
}
}
在项目B中:
public class CachePlanExtension: CachePlan
{
public override CacheSettings GetPlan(ControllerContext filterContext)
{
CacheSettings ca = new CacheSettings();
ca.IsCachingEnabled = true;
ca.Duration = 100;
return ca;
}
}
但永远不会被调用,CashPlan.GetPlan仍然返回null。 Anyidea吗
答案 0 :(得分:3)
您无法“进入”现有类并更改其方法的含义。那将是一个重大的安全漏洞。
答案 1 :(得分:1)
简单地说; “不可能”。正如页面上所解释的那样......
您可以使用扩展方法扩展类或接口,但不能 覆盖他们。具有相同名称和签名的扩展方法 作为接口或类方法将永远不会被调用。在编译时, 扩展方法的优先级始终低于实例方法 在类型本身中定义。换句话说,如果类型有方法 命名为Process(int i),你有一个扩展方法 签名,编译器将始终绑定到实例方法。什么时候 编译器遇到方法调用,它首先查找一个 匹配类型的实例方法。如果找不到匹配,则会 搜索为该类型定义的任何扩展方法,和 绑定到它找到的第一个扩展方法。
答案 2 :(得分:1)
如果你有源代码,为什么不简单地从原始类中删除方法的实现,并在单独的项目中提供扩展方法
答案 3 :(得分:1)
扩展方法只是合成糖,它被编译成静态方法调用。所以你可以编写一个静态方法来完成同样的事情,你根本无法按照你喜欢的方式调用它。如果方法是虚拟的,则可以在派生类中覆盖它。只需确保始终实例化您自己的类型。您也可以使用new
关键字,但是不会使用简单的强制转换和代码。最好是为自己创建一个简单的包装类。该类将有一个有问题的类的实例,并找出正确的调用。这在创建特殊集合时非常常见,因为很多.NET集合类型都不适合继承。但最糟糕的是,你可以使用Moles。
修改强>
创建自己的继承自ActionFilterAttribute
的类,并使用它创建自己的自定义过滤器。
public class MyFilterAttribute : ActionFilterAttribute
{
public override virtual void OnResultExecuting(ResultExecutingContext filterContext)
{
//...
}
}
不推荐在内置属性中覆盖它,但您可以通过各种其他方式挂钩该方法。但如果你真的想这样做,MVC就是开源......
答案 4 :(得分:1)
您可以创建这样的扩展方法(请注意GetPlan() - 参数列表中的this-keyword):
public class CachePlanExtension //does not have to be static
{
public static CacheSettings GetPlan(this CachePlan cachePlan, ControllerContext filterContext) //has to be static!
{
//the cachePlan-Parameter will later contain the CachePlan-object, on which you call this method. Example:
var name = cachePlan.Name;
CacheSettings ca = new CacheSettings();
ca.IsCachingEnabled = true;
ca.Duration = 100;
return ca;
}
}
每当你可以“看到”扩展类(这意味着它必须是公共的或内部的,并且你必须包括扩展类的命名空间)时,你可以调用这样的方法:
new CachePlan().GetPlan(filterContext);
答案 5 :(得分:0)
您可以在继承的类中覆盖该方法。