在子类中转换异常

时间:2012-08-31 13:02:13

标签: c# oop

我有两个ClassA和CLassB类。 ClassA是一个抽象类。 ClassB派生自ClassA。我有一个名为ParentDTO的DTO。

public class ParentDTO
{
    public int UserId { get; set; }
}

public abstract class ClassA
{
    public abstract void CreateUser(ParentDTO dto);
}

public class ClassB : ClassA
{
    public override void CreateUser(ParentDTO dto)
    {
        Console.WriteLine("You are in class ClassB");
    }
}

现在我有一个DTO(MyDTO),它来自ParentDTO。

public class MyDTO: ParentDTO
{
    public int MyID { get; set; }
}

我进一步扩展了ClassB:

public class ClassC : ClassB
{
    public override void CreateUser(ParentDTO dto)
    {
        var mydto = (MyDTO) dto;// This throws cast exception
        mydto.MyID=222;
    }
}

我使用上面的代码:

    ClassC c = new ClassC();
    ParentDTO dto=new ParentDTO();
    c.CreateUser(dto);

有人可以告诉我如何在ClassC的CreateUser方法中强制转换DTO。我想在我的代码中使用mydto.MyID。我知道我正在做一些像动物狮子而不是狮子动物的事情。但有没有办法使用儿童DTO ID?有人可以告诉我,我做错了什么?

5 个答案:

答案 0 :(得分:1)

您只是以错误的方式使用接口架构。添加get,设置为ParentDTO类。

答案 1 :(得分:0)

除非将父类型变量初始化为子类型(或从子类型派生的其他类型),否则不能将父类型变量强制转换为子类型。

ClassC c = new ClassC();
ParentDTO dto = new MyDTO();
c.CreateUser(dto);

答案 2 :(得分:0)

您创建了一个类ParentDTO的实例。将其转换为MyDTO会正确产生此异常,因为该实例的类型为ParentDTO,而非MyDTO类型。
你在那里的对象实例没有名称为MyID的属性,它根本就不存在,所以没有办法得到那个 - 不存在的 - 值。

也许你应该描述一下你想要实现的目标。

答案 3 :(得分:0)

  

有人可以告诉我如何在ClassC的CreateUser方法中投射DTO

没办法。您在声明中使用基类型创建了基类型的对象。你不能把它强制转换为派生类型,这是非法的。 使用

ParentDTO dto=new MyDto();

阅读this

答案 4 :(得分:0)

其他答案是正确的,但是更好地理解“静态类型”和“运行时类型”之间的区别,这种行为的原因会更清楚,他们没有讨论。静态类型是C#代码中变量的类型,而运行时类型是内存中实际对象的类型。

我们都知道静态类型和运行时类型可能不同。考虑:

class A { }
class B : A { }

A a = new B();

变量a指的是B类型的实例。变量的静态类型为A,但对象的运行时类型为B

我们还可以将a视为持有类型A 的引用,引用类型B的实例。当且仅当类型B派生自(或等于)类型A时才允许这样做。

因此,不允许以下内容:

B b = new A();

在这里,您试图将类型A(运行时类型)的实例的引用分配给(静态)类型B的变量.A不是从B派生或等于B,因此不允许赋值。同样,不允许以下分配:

string s = new object();
MyDTO dto = new ParentDTO();

强制转换操作符使某些事情变得复杂,但基本问题是相同的:您试图设置一个引用指向一个对象,该对象的运行时类型不是从或等于静态类型的参考:

A a1 = new A();
B b1 = new B();

A a2 = (A)b1;  // fine, because B is derived from A
B b2 = (B)a1;  // not allowed, because A is not derived from B.

同样,如果我们将object替换为A而将string替换为B,则可能会更有意义:

object a1 = new object();
string b1 = "Hello, World!";

object a2 = (object)b1;  // a2 now points to the string "Hello, World!";
string b2 = (string)a1;  // cast fails: the string variable can't point to an instance of `object`

同样,您的类型:

ParentDTO a1 = new ParentDTO();
MyDTO     b1 = new MyDTO();

ParentDTO a2 = (ParentDTO)b1;  // works
MyDTO     b2 = (MyDTO)a1;;     // doesn't