Generic method type and method parameter does not match [closed]

旧街凉风 提交于 2020-01-04 05:27:45

问题


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!


回答1:


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


来源:https://stackoverflow.com/questions/33407940/generic-method-type-and-method-parameter-does-not-match

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!