通用方法类型和方法参数不匹配

Generic method type and method parameter does not match

我只是无意中发现了这一点,我真的无法解释。说我有那个代码:

public interface IFeature  {  }

public class FeatureA : IFeature { }

class Program
{
  static void Main(string[] args)
  {
    var feature = new FeatureA();
    Load(feature);
  }

  private static void Load(IFeature featureDefinition)
  {
    Activate(featureDefinition);
  }

  private static void Activate<TFeature>(TFeature featureDefinition) where TFeature : IFeature
  {
    var featureType = typeof(TFeature);
    var sameType = featureType == featureDefinition.GetType();
    // sameType == false
  }
}

现在 featureType 始终属于 IFeature 类型,而不是参数 featureDefinition 的类型。有人可以解释为什么吗?

我预计

featureType == featureDefinition.GetType()

是真的...

编辑:

以上是代码的完整工作示例。

现在我很清楚了:参数不是通用的,因此总是 IFeature 类型。我想有一个小的工作示例是有原因的:-P

感谢大家的帮助!

原因是 TFeature 将是调用 Activate 函数的类型。这可以是 IFeature 或任何 class 或实现它的接口。例如,这样调用 Activate 是完全有效的:

Activate<IFeature>(feature);

在这种情况下,编译器使用类型 IFeature 作为类型参数创建泛型方法 Activate,结果是一个完全有效的调用方法。但是,如果你这样称呼它

Activate<Feature>(feature);

其中 Feature 实现 IFeature,那么编译器当然会使用 Feature 作为泛型类型参数,并且该方法再次有效调用。

当你像

这样调用方法时,你可能会遇到困难
Activate(feature);

在那种情况下,编译器会使用他认为最合适的类型,基于编译器一贯的静态分析。它不使用对象的运行时类型,因为这显然不为编译器所知。相反,编译器会尝试推断可用作类型参数的最不常见的类型。

在这种情况下,编译器会检查feature的静态类型实现了哪些接口,如果符合条件,则将feature的静态类型作为泛型类型参数。否则,编译器会抛出泛型类型不明确的错误信息。

例如,您始终可以通过显式覆盖让编译器忘记静态类型:

object objFeature = feature;
Activate(objFeature);

现在,此代码将引发编译器错误,因为 objFeature 的静态类型是 Object,这不满足它应该实现 IFeature 的约束。这与 feature 的真实类型无关,您只能在运行时通过 feature.GetType().

获得

推理样本:

// typeof(TFeature) inside Activate returning `IFeature`:
IFeature f = new FeatureImpl(); 
Activate(f); // compiled into Activate<IFeature>(...) 

// FeatureImpl:FeatureBase:IFeature
// typeof(TFeature) inside Activate returning `FeatureImpl`:
var f1 = new FeatureImpl(); 
Activate(f1); // compiled into Activate<FeatureImpl>(...) 

FeatureBase f2 = new FeatureImpl(); 
Activate(f2); // compiled into Activate<FeatureBase>(...)