2013-04-30 19 views
1

考慮這個People類:如何在運行時創建子類來映射某些屬性,然後將其轉換回父類?

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

我有一些第三方的實現,可以得到人數據,但在一個小的變化。例如,我有一個能夠爲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>(); 

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

+0

你能澄清你所說的「運行時子」的意思。你是指以任何方式使用反射來自動生成代碼? – matcheek 2013-05-01 00:17:11

+0

@matcheek是的,我看着c#類型的構建器,但如果它是做這種事情的唯一方法,我會放棄。 http://msdn.microsoft.com/en-us/library/system.reflection.emit.typebuilder.aspx – cvsguimaraes 2013-05-01 00:27:39

+0

也許你正在尋找的'裝飾Pattern'? http://en.wikipedia.org/wiki/Decorator_pattern – 2013-05-01 01:37:45

回答

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

你甚至不需要鑄造。

+0

很不錯的辦法,但我仍然需要定義子類的打。無論如何,我會用你的解決方案,但我想知道如果我不能在一個更動態的方式創建'StrangePeople'類,如從數據庫中讀取他的屬性和傳遞代表作爲隱式連鑄機... – cvsguimaraes 2013-05-01 03:25:49

+0

@ cvsguimaraes,注意這不是一個新的子類,它是一個新的方法(運算符),在'StrangePeople'類中,我明白你已經擁有了。你還需要創建哪些其他的子類? – 2013-05-01 13:20:03

+0

'StrangePeople'類僅僅是'GetData'正在等待哪種結構的表示形式...... – cvsguimaraes 2013-05-01 13:24:31

1

那麼,根據你願意投入多少努力,你可以使用一個子類動態生成Func s使用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<>真完全操作通用的子類,然後建立這些Func<>當你做你的反思或什麼時候。

這是一種輕率的,但它應該工作。

相關問題