Sameer
Sameer

Reputation: 3173

Implementing generic interface that takes a generic interface as a parameter

I have these two interfaces

    /// <summary>
///     Represents an interface that knows how one type can be transformed into another type.
/// </summary>
/// <typeparam name="TInput"></typeparam>
/// <typeparam name="TOutput"></typeparam>
public interface ITransformer<in TInput,out TOutput>
{
    TOutput Transform(TInput input);
}

public interface ITransform
{
    TOutput Transform<TInput,TOutput>(ITransformer<TInput, TOutput> transformer);
}

I have a class in which in want to implement ITranform like this.

public class MessageLogs :ITransform
{
    // But I am am not able to implement the ITransform interface like this
   // MessageLogs is getting binded in the param but not getting binded to
  // TInput in the Transform<TIn,TOut>  
   // 
    public T Transform<MessageLogs, T>(ITransformer<MessageLogs, T> transformer)
    {
        return transformer.Transform(this);
    } 

}

How to do it correctly without losing the Genericness of the two interfaces? I have many tranformers.

Upvotes: 6

Views: 2835

Answers (2)

Viru
Viru

Reputation: 2246

Change your interface into generics interface instead of method in it

Like below

public interface ITransformer<in TInput, out TOutput>
    {
        TOutput Transform(TInput input);
    }

    public interface ITransform<TInput, TOutput>
    {
        TOutput Transform(ITransformer<TInput, TOutput> transformer);
    }
    public class MessageLogs<T> : ITransform<MessageLogs<T>,T>
    {

        public T Transform(ITransformer<MessageLogs<T>, T> transformer)
        {
            return transformer.Transform(this);
        }

    }

Updated code Let say you do not want MessageLog to know what it is getting tranformed into. then do below.

public class Transformer<T1,T2> : ITransform<T1,T2>
    {

        public T2 Transform(T1 logger,ITransformer<T1, T2> transformer)
        {
            return transformer.Transform(logger);
        }

    }
    public class MessageLogs
    {
       // code specific to message logging
    }

Upvotes: 1

Dennis_E
Dennis_E

Reputation: 8904

The interface requires the implemented method to be generic in both TInput and TOutput. In other words, MessageLogs must be able to accept other types for TInput as well. That's not what you want. You're going to need something like:

public interface ITransformer<in TInput,out TOutput>
{
    TOutput Transform(TInput input);
}

public interface ITransform<TInput>
{
    TOutput Transform<TOutput>(ITransformer<TInput, TOutput> transformer);
}

public class MessageLogs : ITransform<MessageLogs>
{
    public TOutput Transform<TOutput>(ITransformer<MessageLogs, TOutput> transformer)
    {
        return transformer.Transform(this);
    }
}

Upvotes: 3

Related Questions