asp.net mvc 5 -在c#中将基类转换为派生类

本文关键字:基类 转换 派生 mvc net asp | 更新日期: 2023-09-27 18:02:17

我正在尝试将基类转换为派生类对象。见下面的代码,我有问题,当我转换。这是基本的东西,但挣扎。

[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。a班到xyz班。a班?

编辑:

我们正在做i18n项目。所以我们需要用不同的语言显示每个文本。但是我们的EF项目和web项目在不同的Namespace中。这就是我从基类

asp.net mvc 5 -在c#中将基类转换为派生类

派生的原因

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

可以使用linq:

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

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

尽管它们的名字相似,但它们是完全不同的类。就像你把它们叫做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具有类型为ABC.ClassA(或任何IEnumerable<ABC.ClassA>变体)的属性,而不是继承它。

你能确认这是一个实际的要求,或者可以是问题的一部分,如果它解决了你的问题,可以改变吗?

EDIT -基于一个对象从另一个对象继承的事实,参见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));
        }
    }
}