简体   繁体   English

在C#中将基类转换为派生类?

[英]Convert Base class to Derived class in c#?

I am trying to convert Base class to derived class object. 我试图将基类转换为派生类对象。 See below code, I am having the issue when I converting. 参见下面的代码,我在转换时遇到问题。 It is basic thing, but struggling. 这是基本的事情,但正在努力。

[HttpGet]
[Route("/Edit/{Id}")]
public ActionResult Edit(int Id)
{

    List<ClassA> Data = Ctx.GetClassAFromId(Id);

    // Now Here I want convert ABC List<ClassA> to XyZ List<ClassA>
    //How to do that?
    return View(DataXYZ);
}

Model generate by EF EF产生的模型

namespace ABC
{

    public partial class ClassA
    {
           public string First_name { get; set; }
           public string Last_Name { get; set; }
    }
}

Project model 项目模型

namespace XYZ
{
    [MetadataType(typeof(ClassAMetadata))]
    public partial class ClassA:ABC.ClassA
    {

    }   

    public class ClassAMetadata
    {
        [DisplayName(@"First Name")]
        [Required]
        public string First_name { get; set; }


        [DisplayName(@"Last Name")] 
        [Required]       
        public string Last_Name { get; set; }
    }
}

How Can convert ABC.ClassA to XYZ.ClassA? 如何将ABC.ClassA转换为XYZ.ClassA?

Edit: 编辑:

we are working on i18n project. 我们正在从事i18n项目。 So we need to display each text in different languages. 因此,我们需要以不同的语言显示每个文本。 But our EF project is in different Namespace and web project is in different Namespace. 但是我们的EF项目位于不同的命名空间中,而Web项目位于不同的命名空间中。 that is the reason I deriving from base class 这就是我源自基类的原因

Even though their names are alike, they are completely different classes. 即使它们的名称相似,它们也是完全不同的类。 It'd be just the same as if you called them Foo and Bar 就像您将它们称为FooBar

You'll need a method that converts these objects. 您将需要一个转换这些对象的方法。 It takes a Foo object as parameter, then returns an equivalent Bar object 它以Foo对象作为参数,然后返回一个等效的Bar对象

public Bar Foo_To_Bar(Foo myFoo)
{
    return new Bar() { Prop1 = myFoo.Prop1, Prop2 = myFoo.Prop2 };
}

Something like that. 这样的事情。 You'll probably also need a method that goes the other way around if you want to convert in both directions. 如果您想双向转换,您可能还需要一种相反的方法。

Note: If the classes have properties with the same name, I suggest you look into Automapper . 注意:如果这些类的属性具有相同的名称,建议您查看Automapper It automates much of the boring work for you. 它可以自动完成许多无聊的工作。

Edit 编辑
Apparently, your Foo inherits from Bar . 显然,您的Foo继承自Bar That complicates things a bit more. 这使事情变得更加复杂。 I'll rework this answer when I get the time. 有空的时候我会改写这个答案。

I don't see a use case for having your ViewModel (XYZ.ClassA) derive from your base entity (ABC.ClassA). 我没有看到让您的ViewModel(XYZ.ClassA) 您的基本实体(ABC.ClassA) 派生的用例。 Can you explain why this is needed? 您能解释为什么需要这样做吗? I think you're misusing inheritance here. 我认为您在这里滥用继承。

Generally speaking, you'd want your XYZ.ClassA to have a property of type ABC.ClassA (or any IEnumerable<ABC.ClassA> variation), not inherit from it. 一般来说,您希望XYZ.ClassA具有XYZ.ClassA类型的ABC.ClassA (或任何IEnumerable<ABC.ClassA>变体),而不要继承自它。

Can you please confirm if this is an actual requirement, or can be part of the issue and is allowed to change if it fixes your problem? 您能否确定这是否是实际要求,或者可以作为问题的一部分,如果可以解决您的问题,可以更改它吗?

You can't convert List<BaseClass> to List<DerivedClass> 您不能将List<BaseClass>转换为List<DerivedClass>

What you can do is used linq: 您可以使用linq执行以下操作:

listABC.Cast<XYZ.ClassA>.ToList()

But lookout - it is O(n) procedure 但是要注意-这是O(n)程序

EDIT - based on the fact that one object is inherited from the other, see C#/.NET Little Wonders: Use Cast() and OfType() to Change Sequence Type 编辑-基于一个对象是从另一个对象继承的事实,请参见C#/。NET Little Wonders:使用Cast()和OfType()更改序列类型


Couple of options: 几个选择:

1. 1。

namespace ABC
{

    public partial class ClassA
    {
           public ClassA(XYZ.ClassA classToConvert)
           {
             this.First_name = classToConvert.First_name,
             this.Last_Name = classToConvert.Last_Name
           }

           public string First_name { get; set; }
           public string Last_Name { get; set; }
    }
}

Use it singularly: 单独使用:

 var newClassA = new ABC.ClassA((XYZ.ClassA)classA)

Do it in a list: 在列表中执行:

 List<ABC.ClassA> newClassAList = classAList.Select(p => new ABC.ClassA((XYZ.ClassA)p).ToList();

Or do it in a list without the above constructor and using an object initaliser 或者在没有上述构造函数的列表中使用对象初始化器进行操作

 List<ABC.ClassA> newClassAList = classAList.Select(p => new ABC.ClassA{First_name = p.First_name, Last_Name = p.Last_Name}.ToList();
  1. As others have mentioned Use AutoMapper. 正如其他人提到的那样使用AutoMapper。

    • Use Nuget and add AutoMapper to your project (and some initalisation code) 使用Nuget并将AutoMapper添加到您的项目(以及一些初始化代码)
    • Create your Map: 创建地图:

       Mapper.CreateMap<XYZ.ClassA, ABC.ClassA>(); 
    • Map your objects: 映射您的对象:

       var myABCClassA= Mapper.Map<XYZ.ClassA, ABC.ClassA>(myXYZClassA); 
    • As long as your property names on both classes match thats all the code you need 只要两个类的属性名称都匹配,那就是您需要的所有代码

I created this today 我今天创建的

public static void Map<T1, T2>(this T1 obj1, T2 obj2) where T1 : class where T2 : class
{
    IEnumerable<(PropertyInfo p1, PropertyInfo p2)> properties = typeof(T1).GetProperties()
        .Join(typeof(T2).GetProperties(), o => o.Name, t => t.Name, (o, t) => (o, t));
    foreach((PropertyInfo p1, PropertyInfo p2) in properties)
    {
        if (p1.CanWrite && p1.PropertyType == p2.PropertyType)
        {
            p1.SetValue(obj1, p2.GetValue(obj2));
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM