为什么在C#中不允许向下转换?

问题描述 投票:0回答:2

我有2个类别,分别为EventDtoEventWithObjectsDtoEventDto是父类,EventWithObjectsDto从其继承。这些是类:

public class EventDto : BaseDto
{
    public EventTypes Type { get; set; }
    public string Title { get; set; }
    public DateTime StartAt { get; set; }
    public DateTime EndAt { get; set; }
    public Guid? RecursiveCriteriaId { get; set; }
}
public class EventWithObjectsDto : EventDto
{
    public List<ObjectDto> Objects { get; set; }
}

我想将EventDto强制转换为EventWithObjectsDto,所以我尝试了2种方法:抛出var eventWithObjects = (EventWithObjectsDto)ev;InvalidCastException和返回var eventWithObjects = ev as EventWithObjectsDtonull。唯一有效的方法是从: EventDto中删除EventWithObjectsDto并使用AutoMapper将EventDto映射到EventWithObjectsDto,但我不想使用AutoMapper是另一种方法。

而且,我已经做了一个简单的测试:

var simpleEvent = new EventDto();

// Thrown InvalidCastException
var simpleEventWithObjects = (EventWithObjectsDto)simpleEvent; 

有人可以帮我吗?

c# downcast
2个回答
2
投票

您无法将EventDto强制转换为EventWithObjectsDto

因为在OOP理论中,EventDtogeneralized类型,EventWithObjectsDtospecialized类型。

您可以将EventWithObjectsDto强制转换为EventDto,因为EventWithObjectsDtoEventDto 更大]:它包括所有EventDto操作和变量。

您无法将EventDto强制转换为EventWithObjectsDto,因为EventDtoEventWithObjectsDto 小]:它不包括所有EventWithObjectsDto操作和变量。

就像您想说当猫是动物时,所有动物都是猫:您不能,那是错误的。猫是动物,但所有动物都不是猫。

所以您的类型不匹配。

Generalization, Specialization, and Inheritance

Generalization and Specialization - What is the differences

Upcasting and downcasting in C#

What is polymorphism

您所能做的就是使用一种模式,通过检查哪些变量是公共的,在父类的实例中复制具有子类实例的对象。

正在强制转换的对象

必须为类型
EventWithObjectsDto(或派生类型)。

这里有一点小小的地方可以证明,如果是演员表,那将是成功的Event

var a = new EventWithObjectsDto {Type = "Tip"};
EventDto b = a;
var c = (EventWithObjectsDto) b;
Console.WriteLine(c.Type);

输出为:

Tip

EventWithObjectsDto中创建EventDto

虽然无法将类EventDto的对象强制转换为EventWithObjectsDto,但始终可以从父类型的对象创建派生类型的对象。

class EventWithObjectsDto {
    ...
    public EventWithObjectsDto(EventDto e ){(...)}
}


(...)

var simpleEvent = new EventDto();
var simpleEventWithObjects = new EventWithObjectsDto(simpleEvent);

这里是相关的注释表格ECMA-334 5th Edition / December 2017C# Language Specification

隐式或显式的引用转换,永远不会更改要转换的对象的引用身份。 [Note

:换句话说,虽然引用转换可以更改引用的类型,但它永远不会更改所引用对象的类型或值。 尾注]

2
投票

正在强制转换的对象

© www.soinside.com 2019 - 2024. All rights reserved.