在方法需要接口的地方将类传递给方法

本文关键字:方法 接口 | 更新日期: 2023-09-27 18:19:22

我试图在MVC应用程序中使用基于接口的方法。但是,我不能将我的模型(从表单提交到MVC动作的接收)传递给方法,相反,它会抛出一个错误,说

无法从Foo转换为IFoo


编辑:对于那些在我有机会根据评论更新之前粗鲁地删除了我的完整问题的人,这里是我发布的代码项目问题的精确副本,我认为它会让你的生活更容易在那里而不是在这里阅读。

你好,

自从我在这里发帖已经有一段时间了,但我有点心烦意乱,我怎么也记不起我做错了什么。我敢肯定这相当简单,所以希望你能帮上忙。

我有以下(近似的例子):

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

然后我有一个助手类,看起来有点像这样:

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;
    }
}

所以,我遇到的问题是,当我试图将Foo的实例传递给我的助手方法时,我会得到错误:参数类型'Foo'不能赋值给参数类型'IFoo'

我不知道为什么我得到这个错误,因为Foo继承自IFoo和Bar继承自IBar。

相关的附加信息

这就是Foo类最初被填充的方式。这是从网页提交的表单。如果我试图声明Foo为Foo: IFoo我得到错误:无法创建接口的实例。提交表格后。这是一个MVC生成的错误。因此,Foo如上所述使用IFoo

定义
[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);
}

作用域位

这个项目是一个基本的MVC5项目,没有认证。我有一个控制器,使用穷人的DI控制器,是有助手类注入到它。我的MVC模型从接口继承,以允许它们通过。

所以Foo和Bar实际上是数据模型。

在我试图重写它以使用接口之前,这一切都是正常的,因为紧密耦合,我没有任何问题。

所以,我的问题总结:

为什么我得到这个错误,我如何解决它?

如果你需要更多的信息或澄清任何事情,只要大喊:)

希望你能帮上忙。


除此之外,下面的评论是对上述问题的回应,改变了错误:

你可能需要

Foo: IFoo where T: IBar

然后使用

Foo<酒吧>

而不仅仅是Foo

这导致了新的错误:

无法从Foo转换为IFoo


现在,回应关于协方差和逆变的评论,我在研究这个问题时遇到过它,但我不明白为什么它是相关的。我对"泛型"的了解有限,我认为我所做的与接口和DI相关的元素有关。

我很确定有人会认为再次编辑这篇文章是合适的,但现在它已经拥有了所有人来阅读它需要知道的问题是什么以及解决方案是什么(因为有一个标记的答案)。

供参考:这是我第一次张贴的问题原始问题的代码项目

在方法需要接口的地方将类传递给方法

对于泛型类型条件也可以这样做,例如,如果您将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上阅读协方差和逆变性

相关文章: