簡體   English   中英

如何在運行時創建子類以映射某些屬性,然后將其強制轉換回父類?

[英]How can I create subclass at run-time to map some properties then cast it back to parent class?

考慮一下這個People類:

public class People
{
    public virtual string Name { get; set; }    
    public virtual ushort Age { get; set; }
}

我有一些第三方實現可以獲取人員數據,但有一些變化。 例如,我有一個能夠檢索StrangePeople數據的StrangePeople

    public class StrangePeople
    {
        public string Name { get; set; }        
        public DateTime BirthDate { get; set; }
    }
    ...
    StrangePeople someone = GetData<StrangePeople>();

由於類和變量的數量,我試圖找到一種方法來生成可以轉換數據的People的運行時子類,以便我可以稍后將其轉發給People 換句話說,用最少的努力生成如下的子類:

public class StrangePeopleTranslator : People
{
    private ushort? _mAge = null;

    public override ushort Age
    {
        get
        {
            if (_mAge == null)
            {
                DateTime today = DateTime.Today;
                int age = today.Year - BirthDate.Year;
                if (BirthDate > today.AddYears(-age)) age--;
                _mAge = age;
            }

            return _mAge.GetValueOrDefault();
        }
        set
        {
            _mAge = value;
        }
    }

    public DateTime BirthDate { get; set; }
}

...

People someoneElse = (People)GetData<StrangePeopleTranslator>();

也許運行時子類有點矯枉過正......我不知道。

您可以做的最好的事情是提供隱式轉換過載。 這樣你可以從StrangePeople轉換為People ,如下所示:

public class StrangePeople
{
    public string Name { get; set; }
    public DateTime BirthDate { get; set; }

    public static implicit operator People(StrangePeople strangePerson)
    {
        DateTime today = DateTime.Today;
        int age = today.Year - strangePerson.BirthDate.Year;
        if (strangePerson.BirthDate > today.AddYears(-age))
        {
            age--;
        }

        return new People
                    {
                        Name = strangePerson.Name,
                        Age = (ushort) age
                    };
    }

然后你可以這樣做:

People someoneElse = GetData<StrangePeopleTranslator>();

你甚至不需要演員。

好吧,根據您願意投入多少精力,您可以使用System.Linq.Expressions.動態生成Func的單個子類System.Linq.Expressions. 您需要在此處使用C#4來獲得完整功能。

基本理念:

public class Subclass : People
{
    public Func<DateTime, ushort> BirthDateToAge;
    ushort _mAge;

    public override ushort Age
    {
        get { return AgeImpl(_mAge); }
        set { _mAge = value; }
    }
}

// And then somewhere else where you'd want to create the "subclass"
var people = new Subclass();
Func<DateTime, ushort> setter = (Func<DateTime, ushort>)(bday => (ushort)CalcElapsedYears(bday));
people.AgeImpl = setter;

您可能需要以不同的方式對其進行分析,但基本概念是相同的:創建一個可以完全通過Func<> s運行的通用子類,然后在進行反射或諸如此類的東西時構建那些Func<>

它是善良的,但它應該工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM