通用方法类型和方法参数不匹配 [英] Generic method type and method parameter does not match

查看:246
本文介绍了通用方法类型和方法参数不匹配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚偶然发现,我真的不能解释。说我有这样的代码:

  public interface IFeature {} 

public class FeatureA:IFeature {

类程序
{
static void Main(string [] args)
{
var feature = new FeatureA();
Load(feature);
}

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

private static void激活< TFeature>(TFeature featureDefinition)其中TFeature:IFeature
{
var featureType = typeof(TFeature);
var sameType = featureType == featureDefinition.GetType();
// sameType == false
}
}



featureType 总是类型 IFeature ,而不是参数类型 featureDefinition 有人可以解释为什么?



我预期

  featureType == featureDefinition .GetType()

成为真实...


$ b b

edit:



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



现在对我很清楚:参数是非泛型的,因此总是 IFeature 类型。我想有一个小工作例子的原因:-P



感谢帮助家伙!

解决方案

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

 激活< IFeature> 

在这种情况下,编译器使用类型 IFeature 作为类型参数,结果是一个完全有效的调用方法。但是,如果您像

 激活< Feature> 

其中特征 implements IFeature ,那么编译器当然会使用 Feature 作为通用类型参数,并且该方法也可以调用。



当您调用

 激活(功能) ; 

在这种情况下,编译器使用他认为最适合的类型,基于静态分析作为编译器总是做。 不使用对象的运行时类型,因为编译器显然不知道。



在这种情况下,编译器将检查哪些接口是由静态类型实现的类型特征,如果它匹配条件,则特征的静态类型被用作泛型类型参数。



例如,你可以让编译器通过显式覆盖静态类型来忽略它:

  object objFeature = feature; 
Activate(objFeature);

现在,此代码将引发一个编译器错误,因为 objFeature 对象,这不符合它应该实现 IFeature 的约束。这独立于特征的真实类型,它只能在运行时通过 feature.GetType()获得。 p>

不合格样本:

  // typeof(TFeature) IFeature`:
IFeature f = new FeatureImpl();
激活(f); //编译成Activate< IFeature>(...)

// FeatureImpl:FeatureBase:IFeature
// typeof(TFeature)inside Activate returns`FeatureImpl`:
var f1 = new FeatureImpl();
激活(f1); // compile into Activate< FeatureImpl>(...)

FeatureBase f2 = new FeatureImpl();
激活(f2); // compile into Activate< FeatureBase>(...)


I just stumbled over that and I can't really explain that. Say I have that code:

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
  }
}

Now featureType is always of type IFeature and not of the type of the parameter featureDefinition. Can someone explain why?

I expected

featureType == featureDefinition.GetType()

to be true...

edit:

So above is a complete working example of the code.

Now it's quite clear to me: The parameter is non generic, thus always of type IFeature. I guess there is a reason for a small working example :-P

Thanks for the help guys!

解决方案

Thereason is that TFeature will be the type with that the Activate function has been called. This can be IFeature or any class or interface implementing it. For example, it is perfectly valid to call Activate like that:

Activate<IFeature>(feature);

In that case, the compiler creates the generic method Activate using the type IFeature as type parameter and the result is a method that is perfectly valid to call. However, if you call it like

Activate<Feature>(feature);

where Feature implements IFeature, then the compiler will of course use Feature as generic type parameter and again the method is valid to call.

You might have difficulties what happens when you just call the method like

Activate(feature);

In that case, the compiler uses the type that he thinks fits best, based on static analysis as compilers always do. It is not using the runtime type of the object since this is obviously not known to the compiler. Rather, the compiler tries to infer the least common type that can be used as a type parameter.

In this case, the compiler will check what interfaces are implemented by the static type of feature and if it matches the conditions, the static type of feature is used as generic type parameter. Otherwise, the compiler will throw an error message that the generic type is unclear.

For example, you can always make the compiler forget about the static type by explicitly overriding it:

object objFeature = feature;
Activate(objFeature);

Now, this code will raise a compiler error since the static type of objFeature is Object and this does not fulfill the constraint that it should be implementing IFeature. This is independent on the true type of feature which you only get at runtime through feature.GetType().

Inferrence samples:

// 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>(...) 

这篇关于通用方法类型和方法参数不匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆