泛型转换类型不足以检索"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"正确属性

在几乎所有情况下,方法隐藏(new)是错误的;更好的方法是在中几乎所有都使用override。我的主要回答是:移除new

编译器正在做正确的事情;它只通过TScriptManager : ScriptManager知道IsNavigating,所以它使用CC_5也就不足为奇了。c#泛型不像c++模板;他们可以从已知的(where)结构中使用多态性等,并且仅在名称基础上寻找实际T的最佳匹配(鸭子类型)。

如果你真的需要这个,那么要么反射,要么在4.0中,dynamic(完全是duck类型的):

dynamic obj = scriptManager;
if((bool)obj.IsNavigating) {
       ...
}

(注意上面可能会因为"显式接口实现"而失败,但这不是你要做的)