如何从基类初始化派生类



我在。net 6框架下使用c#。我有一门课叫Message和继承MessageTaggedMessage

这个想法很简单。函数接收Message类型的对象,然后向其添加几个Tags,并将其作为TaggedMessage返回。TaggedMessage对象的列表随后显示在一个表中。为了保持良好和简单的数据绑定,我希望TaggedMessage不包含嵌套属性。例如,它不应该保存Message的实例。相反,它应该包含来自Message的所有属性和附加属性。

所以我认为它应该继承Message。然而,我找不到一种方法来实例化TaggedMessage从Message,除非我特别指定每列从Message到TaggedMessage在其构造函数。这似乎过于困难,并且意味着每次向Message添加属性时,都必须重新访问TaggedMessage的构造函数。示例(显然实际情况要复杂得多)

public class Message
{
public string MessageID { get; set; } = "5";
public string Subject{ get; set; } = "Test";
}
Public class TaggedMessage : Message
{
public string MyTag { get; set; }
}

Message m = new Message();
TaggedMessage t = TaggedMessage;
t = (TaggedMessage)m; //This ovbiously doesn't work
t.Tag = "Nature";

现在强制转换不工作,因为我在派生类中强制转换基类。那么,如何把m变成t呢?假设m有50个属性它们在未来会改变。如何获得一个对象t,它具有m的所有值,但添加了额外的标签?一定有比在构造函数中分配所有50个属性更优雅的方法!?我觉得我错过了一个简单的解决方案。

Message对象不能强制转换为TaggedMessage类型。

你要找的是映射,有很多库,包括但不限于Automapper, Mapster或ExpressMapper等。

AutoMapper:

static void Main()
{
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Message, TaggedMessage>()
.IncludeAllDerived();
});
var mapper = config.CreateMapper();
var m = new Message() { MessageID = "SomeMessageID", Subject = "SomeSubject" };
var t = mapper.Map<TaggedMessage>(m);
t.MyTag = "MyTag";
Console.WriteLine(t.MessageID);
Console.WriteLine(t.Subject);
Console.WriteLine(t.MyTag);
}

有一些方法可以完成您想要做的事情,而无需手动编写映射。其中一种方法是使用一个库来为你做这件事,比如Viachaslau建议的AutoMapper。

另一个can可以序列化和反序列化对象:

var message = new Message();
var str = System.Text.Json.JsonSerializer.Serialize(message);
var taggedMessage = System.Text.Json.JsonSerializer.Deserialize<TaggedMessage>(str);
taggedMessage.MyTag = "Nature";

在构造函数中编写该代码的两种替代方法都有其缺点,并且根据用例的不同,可能以各自的方式代价高昂,因此问题不在于是否可以避免,而在于是否应该这样做!

最新更新