1

考虑这个People类:

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

我有一些第三方实现可以获取人员数据,但有一些变化。例如,我有一个能够检索数据的方法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>();

也许运行时子类有点矫枉过正......我不知道。

4

2 回答 2

2

您可以做的最好的事情是提供隐式强制转换重载。这样您就可以从 转换StrangePeoplePeople,如下所示:

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>();

你甚至不需要演员表。

于 2013-05-01T02:58:53.880 回答
1

好吧,根据您愿意为此付出多少努力,您可以使用具有动态生成Funcs的单个子类,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<>在您进行反射或诸如此类的时候构建这些 s。

这有点轻率,但它应该工作。

于 2013-05-01T05:04:18.580 回答