Click here to Skip to main content
15,881,687 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
Hi All,

It's been a while since I've posted here but I'm having a bit of a mare and can't for the life of me remember what I'm doing wrong. I'm pretty sure it's fairly simple so hopefully you can help.

I have the following (approximated example):

C#
public interface IFoo<T>
{   //...some other properties....
   List<T> Bars {get;set;}
}

public interface IBar
{   //...some properties...
}

public class Foo : IFoo<Bar>
{    //...some properties...
    List<Bar> Bars {get;set;}
}

public class Bar : IBar
{ //...some properties...
}


Then I have a helper class which looks a bit like this:

C#
public interface IHelper 
{
   bool DoSomething(IFoo<IBar> model, string path);
}

public class Helper : IHelper
{ 
   public bool DoSomething(IFoo<IBar> model, string path)
   {
       //..Save model to path
       return true;
   }
}


So, the issue I have is when I try to pass an instance of Foo to my helper method I get the error:
Argumet type 'Foo' is no assignable to parameter type 'IFoo<IBar>'

I'm not sure why I get this error because Foo inherits from IFoo and Bar inherits from IBar.

-------------
Additional Info
-------------
This is how the Foo class is initially getting populated. It's a form submission from a webpage. If I try to declare Foo to be Foo: IFoo<IBar> I get the error:
Cannot create an instance of an interface.
upon form submission. This is an MVC generated error. As a result Foo is defined as above using IFoo<Bar>

C#
[HttpPost]
public ActionResult RequestSubmission(Foo model)
{
   if (ModelState.IsValid)
   {
       helper.DoSomething(model, Server.MapPath("/Assets/Template.docx"));
                return Json(new {IsSuccess=true});
   }
   return PartialView("Form", model);
        }


-------------
Bit of scope
-------------
This project is a basic MVC5 project with no authentication.
I have a controller that, using a poor mans DI controller, is having the helper class injected into it.
My MVC models inherit from the interfaces to allow them to be passed through.

So effectively Foo and Bar are data models.

This was all working before I tried to re-write it to use Interfaces, as tightly coupled I had no problems at all.

So, my question in summary:

Why do I get this error, and how can I resolve it?

If you need more information or clarification on anything just yell :-)

Hope you can help.
Posted
Updated 26-Oct-15 1:14am
v2
Comments
phil.o 26-Oct-15 6:58am    
Foo class is defined as IFoo<bar> instead of IFoo<IBar>. Is it a typo?
Pheonyx 26-Oct-15 7:02am    
Its only a typo in that it should read IFoo< Bar > (not lower case bar). Bar implements IBar. Primarily because when I try IFoo< IBar > the MVC form submit fails as it can't map the request data to a model property any more. So my List comes back as blank, in turn failing my data validation.
phil.o 26-Oct-15 7:06am    
Then please show the code where you "try to pass an instance of Foo", especially how you declare and assign this variable.
And I did not clearly understand your answer: Is the Foo class declared as IFoo<IBar> or not?
Pheonyx 26-Oct-15 7:14am    
I've updated the question, please see the new Additional info section for what I hope is clarification.
F-ES Sitecore 26-Oct-15 7:01am    
Have you tried changing the def of Foo to

public class Foo : IFoo<IBar>

Try with these declarations:
C#
public interface IFoo<T>
{   //...some other properties....
   List<T> Bars {get;set;}
}
 
public interface IBar
{   //...some properties...
}
 
public class Foo : IFoo<IBar>
{    //...some properties...
    List<IBar> Bars {get;set;}
}
 
public class Bar : IBar
{ //...some properties...
}

instead.
 
Share this answer
 
Comments
Pheonyx 26-Oct-15 7:23am    
Hi phil.o,

Thanks for this, unfortunately this has been tried and it results in the following:
I get the error:
Cannot create an instance of an interface.
upon form submission. This is an MVC generated error

I've updated my question to include this information.
phil.o 26-Oct-15 7:37am    
Then please show the line where you try to instantiate your Foo variable.
Pheonyx 26-Oct-15 7:42am    
I don't understand what you mean. MVC does that aspect of the code for me. I have a razor view with a form on it. The submit button submits that data to my controller action and in turn MVC map form items to properties on my Foo class.

My form view has this at the top:
@model Models.Foo

my action is declared as per the additional info in the question. What more do you want?
The below came from a response to me posting the same question on stackoverflow and solved the problem for me:


You can also do this with generic type conditions, for example, if you change your IHelper to this:

C#
public interface IHelper
{
    bool DoSomething<t>(IFoo<t> model, string path) where T : IBar;
}</t></t>

You can then implement it:

C#
public class Helper : IHelper
{
    public bool DoSomething<t>(IFoo<t> model, string path) where T : IBar
    {
        //..Save model to path
        return true;
    }
}</t></t>

And calling

C#
someHelperInstance.DoSomething(someInstanceOfFoo, somePath);

No longer throws that error. This is because you are constraining the generic IFoo<t> to be any IBar derived type. You may want to read up on covariance vs contravariance on MSDN.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900