PdxLuke
PdxLuke

Reputation: 27

In C#, why can't I return a derived interface type from a function whose interface signature has the base interface type as its return type?

I'm receiving the compile error: Error CS0535 'COITemplateWriter' does not implement interface member 'iTemplateWriter.Write(iTemplateModel)' TemplateService For the following code:

    public COITemplate Write(COITemplateModel model)
    {
        throw new NotImplementedException();
    }

The interface signature for the above method is as follows:

public interface iTemplateWriter
{
    public iTemplate Write(iTemplateModel model);
}

Type COITemplate implements the iTemplate interface and type COITemplateModel implements the iTemplateModel interface, so why does this code fail? Wouldn't it stand to reason that if the interface requires the method to return anything that implements iTemplate and takes as a parameter anything that implements iTemplateModel that this should compile?

Upvotes: 0

Views: 104

Answers (2)

chancea
chancea

Reputation: 5958

You are confusing what you are allowed to do during run-time with what the compiler needs to know at compile-time.

This is what generics are for in C#

It looks like you want an interface iTemplateWriter where you want to be able to have this method Write that will take in any iTemplateModel and return any iTemplate

You can do this two ways:

Method 1- You can define at the interface level what type of iTemplateModel and what type of iTemplate the implementer of the interface will use:

    public interface iTemplateWriter<TTemplate, TTemplateModel> 
        where TTemplate : iTemplate
        where TTemplateModel : iTemplateModel
    {
         TTemplate Write(TTemplateModel model);
    }

doing this will allow you to define a COITemplateWritter that uses a COITemplate and a COITemplateModel:

public class COITemplateWritter : iTemplateWriter<COITemplate, COITemplateModel>
{
    public COITemplate Write(COITemplateModel model)
    {
        throw new System.NotImplementedException();
    }
}

Use method 1 if you know at compile time what class types the implementing class needs to use

If you need your implementing class to handle all types at run time and you do not know the type at compile-time, then use method 2:

Method 2- You can define this at the method level of what type of iTemplate and what type of iTemplateModel the method will use. This will require all implementing classes to be able to return whatever type is passed in at runtime, which allows for more flexibility but is less structured at compile time.

public interface iTemplateWriter
{
    TTemplate Write<TTemplate, TTemplateModel>(TTemplateModel model)
        where TTemplate : iTemplate
        where TTemplateModel : iTemplateModel;
}

public class COITemplateWritter : iTemplateWriter
{
    public TTemplate Write<TTemplate, TTemplateModel>(TTemplateModel model)
        where TTemplate : iTemplate
        where TTemplateModel : iTemplateModel
    {
        
        throw new System.NotImplementedException();
    }
}

Upvotes: 2

DRapp
DRapp

Reputation: 48129

Without seeing the rest of what COITemplate is, assuming it is not an interface, you should just need to have the function return the interface type itself.

public iTemplateWriter Write(COITemplateModel model)
{
   // if the "COITemplateModel" class is an iTemplateWriter you could just return that back.
   return model;

   // OR if some other object you are working with is that interface.
   return (iTemplateWrite)OfWhateverClassYouAreTrying;

}

Upvotes: 0

Related Questions