C# 在c语言中将基类转换为派生类?
我正在尝试将基类转换为派生类对象。请参阅下面的代码,我在转换时遇到问题。这是最基本的事情,但仍在挣扎C# 在c语言中将基类转换为派生类?,c#,asp.net-mvc-5,C#,Asp.net Mvc 5,我正在尝试将基类转换为派生类对象。请参阅下面的代码,我在转换时遇到问题。这是最基本的事情,但仍在挣扎 [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
[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);
}
项目模型
如何将ABC.ClassA转换为XYZ.ClassA
编辑:
我们正在进行i18n项目。所以我们需要用不同的语言显示每个文本。但我们的EF项目位于不同的命名空间中,而web项目位于不同的命名空间中。这就是我从基类派生的原因尽管它们的名称相似,但它们是完全不同的类。就像你叫他们Foo和Bar一样 您需要一个转换这些对象的方法。它接受一个Foo对象作为参数,然后返回一个等价的Bar对象 差不多吧。如果您想在两个方向上进行转换,您可能还需要一个相反的方法 注意:如果类具有相同名称的属性,我建议您查看。它使你的许多枯燥工作自动化 编辑 显然,你的食物是从酒吧继承来的。这让事情变得更复杂了。等我有时间的时候,我会重做这个答案 我看不到从基本实体ABC.ClassA派生ViewModel XYZ.ClassA的用例。你能解释一下为什么需要这样做吗?我认为你在滥用继承权 一般来说,您希望您的XYZ.ClassA具有ABC.ClassA类型的属性或任何IEnumerable变体,而不是从中继承 您能否确认这是一个实际需求,或者是问题的一部分,并且如果它解决了您的问题,您可以更改它吗?您不能将列表转换为列表 您可以使用linq:
listABC.Cast<XYZ.ClassA>.ToList()
但是lookout-它是在过程编辑中-基于一个对象从另一个对象继承的事实,请参见 两种选择: 一, 要特别使用它:
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();
正如其他人提到的,使用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));
}
}
}
请查看使用automapper或为XYZ.ClassA编写构造函数,该构造函数将ABC.ClassA作为参数,并从中适当分配字段。您不能简单地“转换”类型转换它。您需要复制属性。这让我想知道为什么你们有两个不同的模型,它们不是完全不同的类。一个来自另一个,是的,这通常意味着一些属性具有相同的名称。@HenkHolterman:想想看,这是一个奇怪的问题。如果两个类都可以直接相互转换,为什么它们会相互继承?我正试图找到一个用于此的用例,但我画了一个空白。在OP的示例中,他的派生类实际上是他的ViewModel。我是现在很困惑。@Flater,我们正在进行i18n项目。所以我们需要用不同的语言显示每个文本。但我们的EF项目位于不同的命名空间中,而web项目位于不同的命名空间中。这就是我从基类派生的原因。就像我说的,派生不是你想要的,你在滥用它。将viewmodel视为一组数据。但是,在MVC应用程序中直接使用实体也是危险的。我建议您将当前实现更改为基本实体ABC.ClassA,这是一个结构类似于XYZ.ClassADTO的DTO,然后是一个具有XYZ.ClassADTO类型属性或其IEnumerable变体的Viewmodel XYZ.MyFancyViewModel。
List<ABC.ClassA> newClassAList = classAList.Select(p => new ABC.ClassA{First_name = p.First_name, Last_Name = p.Last_Name}.ToList();
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));
}
}
}