泛型转换类型不足以检索"new"正确属性
本文关键字:quot 属性 new 转换 检索 泛型 类型 不足以 | 更新日期: 2023-09-27 18:16:07
我有一个问题需要解决。
为了进行单元测试,我有一个伪ScriptManager类型,定义如下:public class FakeScriptManager : ScriptManager
{
public new virtual bool IsNavigating { get; private set; }
}
我测试的方法是这样的:
public string GetHistoryPoint<TScriptManager>(string key, TScriptManager scriptManager)
where TScriptManager : ScriptManager
{
TScriptManager realScriptManager = Convert.ChangeType(scriptManager, scriptManager.GetType());
if (realScriptManager.IsNavigating)
{
// Do something
}
}
测试方法如下:
using (FakeScriptManager scriptManager = new FakeScriptManager(true, false))
{
object value = _handler.GetHistoryPoint(keyExists, scriptManager);
}
我打算设置NEW属性IsNavigating is true for FakeScriptManager变量。但这是不可能的。变量realScriptManager似乎无法从预期的通用TScriptManager类型中强制转换。
注意:调试,尝试直接转换输入参数scriptManager与具体类型FakeScriptManager,它是ok的。
所以,我的问题是:如何使泛型GetHistoryPoint方法像我期望的那样正常工作?谁来帮我一把?
在几乎所有情况下,方法隐藏(new
)是错误的;更好的方法是在中几乎所有都使用override
。我的主要回答是:移除new
。
编译器正在做正确的事情;它只通过TScriptManager : ScriptManager
知道IsNavigating
,所以它使用CC_5也就不足为奇了。c#泛型不像c++模板;他们可以从已知的(where
)结构中使用多态性等,并且不仅在名称基础上寻找实际T
的最佳匹配(鸭子类型)。
如果你真的需要这个,那么要么反射,要么在4.0中,dynamic
(完全是duck类型的):
dynamic obj = scriptManager;
if((bool)obj.IsNavigating) {
...
}
(注意上面可能会因为"显式接口实现"而失败,但这不是你要做的)