无法将基础转换为派生类

时间:2018-10-30 12:22:01

标签: c# architecture .net-core

正在这里培训的系统开发人员...

我处于.net核心项目的中间,我们在其中尝试制作“精美的体系结构”。

当前,我们有以下项目: 模型,DAL,BLL,UI(也按此顺序引用)。

但是,我们刚刚决定从实体框架切换到dapper,因此我们将从ef松散延迟加载和其他功能。

我的解决方案在models类中,删除“基本”模型项目中的引用,并在BLL中具有“派生”类。

但是,当我当时使用BL层存储库时,我发现自己需要从基本模型类转换为派生的扩展模型,给我一个InvalidCastException

我哪里出错了?从一开始就这样做的“正确”方法是什么?

示例

在我的模型项目中,我将拥有class foo,并且在BLL中将拥有一个类:class foo : Models.foo,然后在BLL存储库class fooRepository中将拥有类似的方法:

public foo GetFooById(int Id) {
    return (foo)DAL.FooRepository.GetById(Id) 
}
  • 这里的foo将构成BLL中的模型扩展,但DAL中的一个将是foo的基类。

具体的可编译示例:https://github.com/jona8690/ChildInheritanceExample

2 个答案:

答案 0 :(得分:1)

您可以通过反射或通过检查属性来判断该“水果”是否为“苹果”,然后仅投射它是否能够成为“苹果”?

捕获从存储库对象返回的对象,检查/比较该对象的对象的结果。GetType()结果,仅在适当时返回强制转换/转换对象,否则进行适当的null返回或错误响应?

答案 1 :(得分:1)

好,这花了我一段时间。我大致猜到了您要击中的内容,但是您的类实际上与它的祖先具有相同的名称,但是在不同的命名空间中,因此对代码的第一次读取实际上显示出您的dal和bll使用相同的类。

那为什么不起作用?答案归结为您在投射对象时正在做什么和没有做什么。您实际上并不是在改变对象。强制转换只是将编译时检查移动为运行时检查。让我们简化您的示例。

这将起作用:

object o = new Foo();
Foo myFoo = (Foo)o;

这将编译,但在运行时将抛出您的invalidcastexception。

object o = new Bar();
Foo myFoo = (Foo)o;

为什么?因为Bar不是Foo。

或者在上面的评论中使用有用的水果示例。

public class Fruit {}
public class Banana : Fruit {}
public class Apple : Fruit {}

private Fruit getFruit()
{
  return new Banana();
}

private void DoSomething()
{
  Apple apple = (Apple)this.getFruit(); // obviously can't cast
}

但是,我听到您提出抗议,我的情况有所不同,因为苹果并非来自香蕉。确实如此,但是请记住,除了基本的Fruit类之外,Apple还具有其他属性和方法,应用程序在处理已知为Apple的事物时可以使用的方法或属性,但是没有其他Fruity类型。

在您的情况下,您期望的酒吧类型会比您的委托人提供的更为专业