Home > Back-end >  Foo<T> where T is interface or implementation
Foo<T> where T is interface or implementation

Time:01-31

I have this:

var newFoo = new Foo<Car>();

DoSomething(newFoo);


void DoSomething(Foo inputFoo)
{
    if (inputFoo is Foo<IDrivable> f) Console.WriteLine("It is a Foo<IDrivable>.");
    else Console.WriteLine("Nope, not a Foo<IDrivable>.");
}

public abstract class Foo { }
public class Foo<T>:Foo { }
public interface IDrivable { }
public class Car : IDrivable { }

This prints "Nope, not a Foo<IDrivable>".

Is it possible to perform a contravariant check on T somehow? How do I refactor the above to print "It is a Foo<IDrivable>"given a Foo<Car>?

CodePudding user response:

You can check whether there is a generic parameter and whether (the first one) is assignable to IDrivable.

var firstTypeParameter = inputFoo.GetType().GenericTypeArguments.FirstOrDefault();
if (firstTypeParameter != null && firstTypeParameter.IsAssignableTo(typeof(IDrivable)))
    Console.WriteLine("It is a Foo<IDrivable>");

Edit:

As noted in a comment, a more elegant solution can be achieved if you're willing to introduce another interface:

public interface IFoo<out T> { }
public class Foo<T> : Foo, IFoo<T> { }

The check then becomes

if (inputFoo is IFoo<IDrivable> f) 
    Console.WriteLine("It is a Foo<IDrivable>.");

CodePudding user response:

var newFoo = new Foo<Car>();

DoSomething(newFoo);


void DoSomething(Foo inputFoo)
{
    if (inputFoo.GetType().GetGenericTypeDefinition() == typeof(Foo<>) && typeof(IDrivable).IsAssignableFrom(inputFoo.GetType().GetGenericArguments()[0])) Console.WriteLine("It is a Foo<IDrivable>.");
    else Console.WriteLine("Nope, not a Foo<IDrivable>.");
}

public abstract class Foo { }
public class Foo<T>:Foo { }
public interface IDrivable { }
public class Car : IDrivable { }
  • Related