Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

We have a service with provides us with a list features (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

  • using reflection
  • using a dynamic variable to determine the type on runtime (Calling a generic method with the correct derived type)

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 :-)

like image 293
DerApe Avatar asked Oct 29 '15 08:10

DerApe


People also ask

Can you create an instance of generic interface?

In similar way, we can create generic interfaces in java. We can also have multiple type parameters as in Map interface. Again we can provide parameterized value to a parameterized type also, for example new HashMap<String, List<String>>(); is valid.

CAN interfaces have generics?

Generic interfaces can inherit from non-generic interfaces if the generic interface is covariant, which means it only uses its type parameter as a return value.

How can use generics with interface in C#?

You can declare variant generic interfaces by using the in and out keywords for generic type parameters. ref , in , and out parameters in C# cannot be variant. Value types also do not support variance. You can declare a generic type parameter covariant by using the out keyword.

How do you invoke a generic method?

To call a generic method, you need to provide types that will be used during the method invocation. Those types can be passed as an instance of NType objects initialized with particular . NET types.


1 Answers

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);
    }
}
like image 103
Sriram Sakthivel Avatar answered Sep 22 '22 20:09

Sriram Sakthivel