簡體   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