Prisoner ZERO
Prisoner ZERO

Reputation: 14176

Implementing interfaces using generics

I'm new to generics and need some help.

I want to create an interface for all "transformer" classes to implement. To be a "transformer" the class must contain at least one variation of T mapTo<T>(T t).

HERE IS HOW I WANT TO USE TRANSFORMERS:
Overload some methods...GREAT! Seems easy enough!

public class Transformer : ITransformer
{
    public Transformer(IPerson instance)
    {
    }

    public XmlDocument mapTo(XmlDocument xmlDocument)
    {
        // Transformation code would go here...
        // For Example:
        // element.InnerXml = instance.Name;

        return xmlDocument;
    }

    public UIPerson maptTo(UIPerson person)
    {
        // Transformation code would go here...
        // For Example:
        // person.Name = instance.Name;

        return person;
    }
}

LET'S USE GENERICS TO DEFINE THE INTERFACE:
Greate idea!

public interface ITransformer
{
     T MapTo<T>(T t); 
}

THE PROBLEM:
If I use generics in the interface my concrete class is LITERALLY forced to implement the following:

public T MapTo<T>(T t)
{
    throw new NotImplementedException();
}

THIS MAKES THE CLASS LOOK RATHER UGLY

public class Transformer : ITransformer
{
    public Transformer(IPerson  instance)
    {
    }

    public XmlDocument MapTo(XmlDocument xmlDocument)
    {
        // Transformation code would go here...
        // For Example:
        // element.InnerXml = instance.Name;

        return xmlDocument;
    }

    public UIPerson MapTo(UIPerson person)
    {
        // Transformation code would go here...
        // For Example:
        // person.Name = instance.Name;

        return person;
    }

    public T MapTo<T>(T t)
    {
        throw new NotImplementedException();
    }
}

Upvotes: 0

Views: 212

Answers (5)

Edmond Wong
Edmond Wong

Reputation: 161

public interface ITransformer<in TIn, out TOut>
{
    TOut Transform(TIn from);
}

public abstract class TransformerBase : ITransformer<IGatewayMessage, 
IMessageDto>
{
    public abstract IMessageDto Transform(IGatewayMessage source);
}

internal class GenericTransformer<TPayload> : TransformerBase where TPayload: class, IMessageDto, new() {
    TPayload payload;
    payload = ((aPayloadType) source.aPayload) as TPayload;
    payload.additionalProperty = source.additionalProperty;
    return payload;
}

Upvotes: 0

Alexander R
Alexander R

Reputation: 2476

You need to make the ITransformer interface generic. So, you want this:

public interface ITransformer<T>
{
    public T MapTo(T t);
}

Then, when implementing the interface, classes can pass the interface the type parameter of the class that they wish to use:

public class Transformer : ITransformer<XmlDocument>
{
    public XmlDocument MapTo(XmlDocument t)
    {
        //...
    }
}

Edit: As lazyberezovsky said below, there's nothing stopping you from implementing the same interface multiple times:

public class Transformer : ITransformer<XmlDocument>, ITransformer<UIPerson>

Which must, of course provide implementations for XmlDocument MapTo(XmlDocument t) and UIPerson MapTo(UIPerson t).

Upvotes: 1

Sergey Berezovskiy
Sergey Berezovskiy

Reputation: 236328

Maybe add generic parameter to interface definition:

public interface ITransformer<T>
{
     T MapTo(T t); 
}

And implement all mappings you need:

public class Transformer : ITransformer<XmlDocument>, ITransformer<UIPerson>

Upvotes: 2

Mekswoll
Mekswoll

Reputation: 1433

I think what you're trying to do is have the following interface:

public interface ITransformer<TEntity> {
    public TEntity MapTo(TEntity entity);
}

Upvotes: 0

tobias86
tobias86

Reputation: 5029

Try this:

public interface ITransformer<T>
{
    T MapTo(T t);
}

Then when you implement your interface, your class looks like:

public class Transformer : ITransformer<XmlDocument>
{
    public XmlDocument MapTo(XmlDocument t)
    {
        throw new NotImplementedException();
    }
}

Upvotes: 1

Related Questions