简体   繁体   English

使用接口实例调用泛型方法

[英]Calling a generic method with interface instances

As a followup question to this one 作为对此的后续问题

public interface IFeature  {  }

public class FeatureA : IFeature { }

IFeature a = new FeatureA();
Activate(a);

private static void Activate<TFeature>(TFeature featureDefinition) where TFeature : IFeature
{

}

I undestand, that once the FeatureA is casted to IFeature the generic method will always get IFeature as type parameter. 我没有理解,一旦FeatureA被转换为IFeature ,泛型方法将始终将IFeature作为类型参数。

We have a service with provides us with a list features ( List<IFeature> ). 我们有一项服务,为我们提供了一个列表功能( List<IFeature> )。 If we want to iterate over those features, passing each in the generic method, I guess there is no way to get the concrete type in the generic method other than 如果我们想迭代这些特性,在泛型方法中传递每个特征,我想没有办法在泛型方法中获得具体类型而不是

Since reflection is very costly, I would like to use the dynamic cast. 由于反射非常昂贵,我想使用动态转换。 Is there any downside to call the method that way? 以这种方式调用方法有什么缺点吗? Somehow I feel dirty when doing that :-) 不知怎的,我这样做时感觉很脏:-)

You can use visitor pattern as follows assuming that you can modify your codebase. 假设您可以修改代码库,则可以使用以下访问者模式。 Otherwise, use dynamic. 否则,使用动态。

public interface IFeature
{
    void Accept(Visitior visitor);
}

public class FeatureA : IFeature
{
    public void Accept(Visitior visitor)
    {
        visitor.Visit(this);
    }
}

public class FeatureB : IFeature
{
    public void Accept(Visitior visitor)
    {
        visitor.Visit(this);
    }
}

public class Visitior
{
    public void Visit<TFeature>(TFeature feature) where TFeature : IFeature
    {
        Console.WriteLine(typeof(TFeature) == feature.GetType());//True
    }
}

static void Main(string[] args)
{
    List<IFeature> features = new List<IFeature>
    {
         new FeatureA(),
         new FeatureB()
    };

    Visitior visitor = new Visitior();
    foreach (var item in features)
    {
        item.Accept(visitor);
    }
}

You can obtain the type object for generic/(not generic) type using typeof: 您可以使用typeof获取泛型/(非泛型)类型的类型对象:

    public static T Parse<T>(String value)
    {
        object result = default(T);
        var typeT = typeof (T);
        if (typeT == typeof(Guid))
        {
            result = new Guid(value);
        }
        else if (typeT == typeof(TimeSpan))
        {
            result = TimeSpan.Parse(value);
        }
        else
        {
            result = Convert.ChangeType(value, typeT);
        }
        return (T)result;
    }

My simple method returns T. And this is a key point. 我的简单方法返回T.这是一个关键点。 It must be generic to allow developer to specify return type. 允许开发人员指定返回类型必须是通用的。 If method doesn't return generic and only accepts one then there are several reasons to make it generic. 如果方法不返回泛型并且只接受一个,则有几个原因使它成为通用的。 To avoid box/unbox operations on method arguments or to tackle with situation when method takes argument of different types which are not inherited from common base class/interface. 避免对方法参数进行box / unbox操作,或者当方法接受不是从公共基类/接口继承的不同类型的参数时解决这种情况。 And it's not your case. 而且不是你的情况。 So the method in your code haven't to be generic. 因此,代码中的方法不必是通用的。 Just type you argument as IFeature and use is/as/GetType(): 只需将您的参数键入为IFeature,并使用/ as / GetType():

private static void Activate(IFeature feature) 
{
   if (feature is FeatureImplementationA)
   {
      //Do something...
   }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM