Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing interface with generic type that is less constrained than that of a method I need to call

Tags:

c#

generics

I'm implementing an interface in order to inject custom business logic into a framework that utilizes Microsoft Unity. My core issue is that a the interface I need to implement defines the following method:

T InterfaceMethod<T>();

T has no constraints. In my code, I need to call a method from a different 3rd party library, with a method signature of

T AnotherMethod<T>() where T: class;

The type T is significant to the logic of AnotherMethod. Is there any way to call AnotherMethod<T>() within my implementation, without using reflection? I obviously need to take alternate action if T is a value type. Is there perhaps a way to autobox to work around this?

like image 449
nickwesselman Avatar asked Jul 25 '12 01:07

nickwesselman


People also ask

What does the generic constraint of type interface do?

Interface Type Constraint You can constrain the generic type by interface, thereby allowing only classes that implement that interface or classes that inherit from classes that implement the interface as the type parameter.

Can a generic implement an interface?

Only generic classes can implement generic interfaces. Normal classes can't implement generic interfaces.

What is generic type constraint?

The where clause in a generic definition specifies constraints on the types that are used as arguments for type parameters in a generic type, method, delegate, or local function. Constraints can specify interfaces, base classes, or require a generic type to be a reference, value, or unmanaged type.


2 Answers

I am not sure this is exactly what you need, but this allows you to call AnotherMethod from InterfaceMethod without using reflection. It still uses a Convert.ChangeType though.

The idea is to make the implementation of the class generic with a constrain (here Tin). Then you convert the unconstrained type T of the InterfaceMethod to Tin. Finally you can call the AnotherMethod with the constrained type. The following works fine with strings.

public interface ITest
{
    T InterfaceMethod<T> (T arg);
}

public interface ITest2
{
    U AnotherMethod<U>(U arg) where U : class;
}

public class Test<Tin> : ITest, ITest2 where Tin : class
{
    public T InterfaceMethod<T> (T arg)
    {
        Tin argU = arg as Tin;
        if (argU != null)
        {
            Tin resultU = AnotherMethod(argU);
            T resultT = (T)Convert.ChangeType(resultU,typeof(T));
            return resultT;
        }
        return default(T);
    }

    public U AnotherMethod<U> (U arg) where U : class { return arg; }
}
like image 102
edeboursetty Avatar answered Nov 15 '22 06:11

edeboursetty


I don't think that what you're looking for is possible without reflection. At best, you could just call AnotherMethod<object>() and cast the result. But this would only really work right if AnotherMethod's T isn't important for your purposes.

like image 38
Tim S. Avatar answered Nov 15 '22 07:11

Tim S.