繁体   English   中英

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

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

我试图将基类转换为派生类对象。 参见下面的代码,我在转换时遇到问题。 这是基本的事情,但正在努力。

[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);
}

EF产生的模型

namespace ABC
{

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

项目模型

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; }
    }
}

如何将ABC.ClassA转换为XYZ.ClassA?

编辑:

我们正在从事i18n项目。 因此,我们需要以不同的语言显示每个文本。 但是我们的EF项目位于不同的命名空间中,而Web项目位于不同的命名空间中。 这就是我源自基类的原因

即使它们的名称相似,它们也是完全不同的类。 就像您将它们称为FooBar

您将需要一个转换这些对象的方法。 它以Foo对象作为参数,然后返回一个等效的Bar对象

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

这样的事情。 如果您想双向转换,您可能还需要一种相反的方法。

注意:如果这些类的属性具有相同的名称,建议您查看Automapper 它可以自动完成许多无聊的工作。

编辑
显然,您的Foo继承自Bar 这使事情变得更加复杂。 有空的时候我会改写这个答案。

我没有看到让您的ViewModel(XYZ.ClassA) 您的基本实体(ABC.ClassA) 派生的用例。 您能解释为什么需要这样做吗? 我认为您在这里滥用继承。

一般来说,您希望XYZ.ClassA具有XYZ.ClassA类型的ABC.ClassA (或任何IEnumerable<ABC.ClassA>变体),而不要继承自它。

您能否确定这是否是实际要求,或者可以作为问题的一部分,如果可以解决您的问题,可以更改它吗?

您不能将List<BaseClass>转换为List<DerivedClass>

您可以使用linq执行以下操作:

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

但是要注意-这是O(n)程序

编辑-基于一个对象是从另一个对象继承的事实,请参见C#/。NET Little Wonders:使用Cast()和OfType()更改序列类型


几个选择:

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; }
    }
}

单独使用:

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

在列表中执行:

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

或者在没有上述构造函数的列表中使用对象初始化器进行操作

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

    • 使用Nuget并将AutoMapper添加到您的项目(以及一些初始化代码)
    • 创建地图:

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

       var myABCClassA= Mapper.Map<XYZ.ClassA, ABC.ClassA>(myXYZClassA); 
    • 只要两个类的属性名称都匹配,那就是您需要的所有代码

我今天创建的

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