2015-10-27 27 views
0

我想在MVC應用程序中使用基於接口的方法。然而,我無法將模型(從表單提交收到一個MVC動作)傳遞給方法,而是拋出了一個錯誤,說發佈將類傳遞給方法所期望的接口的方法

Cannot convert from Foo<Bar> to IFoo<IBar>


編輯:對於那些誰面前毫不客氣地打消了我完整的問題我有機會根據這裏的評論對它進行更新,這是我發佈的CodeProject問題的完全重複,並且認爲它會讓你的生活更容易閱讀,而不是在這裏閱讀。

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):

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:

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>

[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.


除此之外以下注釋是響應於改變了錯誤上述問題作出:

You might need

Foo : IFoo<T> where T : IBar

Then use

Foo<Bar>

rather than just Foo

這導致了新的錯誤:

無法從富<欄>轉換爲IFoo的<伊巴爾>現在


,在回答有關協變和逆變,我的評論在我研究這個問題時遇到了一些問題,但我不明白爲什麼它是相關的。我對「泛型」的瞭解有限,我認爲我所做的與界面和DI相關的元素有關。

我很確定有人會認爲適當的再​​次編輯它,但它現在擁有一切來閱讀它的人需要知道什麼是問題和解決方案是什麼(因爲有一個標記回答)。

供參考:這是我第一次張貼的問題Original Question on Code Project

+0

codeproject不爲我加載。最好把你所有的問題放在這裏。代碼項目是代碼項目。 stackoverflow是stackoverflow。不要分享鏈接 –

+0

@Servy最佳編輯! :) – DavidG

+0

*你需要的是反轉。不幸的是,你不能使用它,因爲你的'List '。基本上,由於「IFoo 」,您的列表被創建爲「列表」。但是,您嘗試將您的對象投射到「IFoo 」,因此您的收藏將轉到「列表」。那麼這意味着有人可以添加一個不是「Bar」的對象,從而導致編譯錯誤。你需要刪除'List'(並且使用一個不可變的類型),或者放棄衝突 –

回答

1

你也可以做到這一點與一般類型的條件,例如,如果你改變你的IHelper這樣:

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

你可以然後實現它:

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

,並呼籲

someHelperInstance.DoSomething(someInstanceOfFoo, somePath); 

不再拋出該錯誤。這是因爲您將通用IFoo<T>限制爲任何IBar派生類型。您可能需要閱讀MSDN上的covariance vs contravariance

+0

感謝您的有益迴應。這正是問題所在。我只是不知道如何使它與方法調用一起工作。 – Pheonyx

相關問題