2013-06-05 62 views
0

調用unknowed的構造,我有這樣的情況: 我有類represeting性質:在編譯時類

public abstract class RootProperty { 
    public int Id {get; set;} 
} 
public class AProperty {} 
public class BProperty {} 

,並讓有這些的looot:

public class ZProperty {} 

而且一每個屬性的值,

public abstract class RootValue { 
    public RootProperty Property {get;set;} 
} 
public class AValue : RootValue { 
    public AValue(AProperty) { ... } 
    public string Value {get; set;} 
} 
public class ZValue : RootValue { 
    public ZValue(ZProperty) { ... } 
    public sometipe Value {get;set;} } 

實際上,每個類都代表一種類型財產比事物必須具有的。所以,如果我想說的是,一個屬性由一個字符串至極定義必須在一個給定的域值,我說:

public class DomainProperty { 
    public ICollection<string> Domain {get; set;} 
} 
public class DomainValue { 
    public DomainValue(DomainProperty) {...} 
    public string Value 
    { 
     set { 
      if (!this.Property.Domain.Any(d=>d==value)) { 
       throw new Exceptin("Value out of range!"); 
      } 
     } 
    } 
} 

這樣我就可以狗可以大或小,而我的大。

DomainProperty DogsSize = new DomainProperty { Domain= ["big","small"] } 
DomainValue MyDogSize = new DomainValue(color) { Value = "big" } 

利用這一點,我可以用最大值和最小值定義的數值範圍屬性等等歐凱,這裏的第一個問題是:¿你能想到的coustomizable各類物業的這個問題的一些其他的解決辦法? ?

現在,讓我在這裏發表的questio: 前面的邏輯在服務器端,它從客戶端reciving抽象DTOS的列表:

public abstract class RootDto { public int PropertyId {get; set; } } 
public class ADto : RootDto { public string Value {get; set;} } 
pubic class BDto: RootDto { public bool Value {get;set;} } 
public class ZDto : RootDto {public someothertype Value {get; set;}} 

隨着RootDto屬性ID我可以找到原始的RootProperty。我想創建一個新的?Value實例,並將該值設置爲?Dto.Value。 現在我有這個在很多鑄件:

List<RootDto> listDto; 
foreach(dto in listDtio) { 
    if (someDto is ADto) { 
     ADto castedDto = (ADto) dto; 
     AProperty dtoProperty = (AProperty) Repository.findRootProperty(dto.PropertyId); 
     AValue valueForDto = new AValue(dtoProperty); 
     valueForDto.Value = castedDto.Value; 
    } 
    if ...(B.....Z) 
} 

這樣的作品,但如果你有宋衍濤行代碼的戰利品說,15更多鈔票財產類。 我已經調查過反射和動態類型,但沒有發現任何東西,你能幫我嗎? 感謝您的時間,我希望我給了一個很好的解釋

回答

2

您的代碼很混亂,所以我的答案代碼也不是最好的,但是如果您瞭解代碼,就可以理解答案。

第一種方法我會嘗試是仿製藥:

首先提出一些抽象的價值得到,根類設置:

public abstract class RootValue 
{ 
    public RootProperty Property {get;set;} 
    public abstract object ValueInRoot {get; set;} 
} 

public abstract class RootDto 
{ 
    public int PropertyId {get; set; } 
    public abstract object ValueInRoot {get; set; } 
} 

既然你在最後的方法創建新AProperty,我相信它也繼承了RootProperty,所​​以RootProperty也應該遵循上面的想法。但我相信你會發現Property類可能不需要。 (見ValueClass評論) 標識表明RootProperty有一個CreateValue方法:

public abstract class RootProperty 
{ 
    public int Id {get; set;} 

    public abstract RootValue CreateValue(); 
} 

如果你有AProperty通過ZProperty,使用一個類的聲明是這樣的。 它是一個通用類,它接受一個類型參數(TValue),這在編譯時是未知的。

//I really believe the properties are inheriting RootProperty 
public class Property<TValue> : RootProperty 
{ 
    public ValueClass<TValue> CreateTypedValue() 
    { 
     //Create the new ValueClass<TValue> here; 
     //I believe it's the best place to do that. 

     //It will know the type and it can be called via the 
     //overriden method below 

     //This way you avoid calling the Value contructor in your 
     //final method. 
    } 

    public override RootValue CreateValue() 
    { 
     return this.CreateTypedValue(); 
    } 
} 

如果你有安勤通過量ZValue,使用,從而覆蓋根值: (當心,因爲我不知道你是怎麼在這裏使用的屬性,看看在構造函數中的評論看主意)

public class ValueClass<TValue> : RootValue 
{ 
    //this line is not clear for me.... 
    public ValueClass(Property<TValue>) 
    { 
     //I believe you should leave the task of creating this ValueClass to the 
     //Property CreateTypedValue() method. 

     //See that I added the CreateValue in te property classes, 
     //you will see further on why I did that. It solves constructor problem. 
    }   

    public TValue Value {get; set;} 

    public override object ValueInRoot 
    { 
     get { return Value; } 
     set { Value = (TValue)value; } 
    } 
} 

對於域:

public class DomainProperty<TValue> 
{ 
    public ICollection<TValue> Domain {get; set;} 
} 

public class DomainValue<TValue> 
{ 
    public DomainValue(DomainProperty<TValue>) {...} 
    public TValue Value 
    { 
     set { 
      //Here I'd use Domain.Contains(value) 
      if (!this.Property.Domain.Any(d=>d==value)) 
      { 
       throw new Exceptin("Value out of range!"); 
      } 
     } 
    } 
} 

對於DTO的,這也將覆蓋根值:

public class Dto<TValue> : RootDto 
{ 
    public TValue Value {get; set;} 
    public override object ValueInRoot 
    { 
     get { return Value; } 
     set { Value = (TValue)value; } 
    } 
} 

最後,在服務器上的分配方法:

foreach(dto in listDtio) 
{ 
    //if (someDto is ADto) 
    //{ 
     //ADto castedDto = (ADto) dto; 
     RootProperty dtoProperty = Repository.findRootProperty(dto.PropertyId); 

     //here is the way you solve your constructor problem. 
     RootValue valueForDto = dtoProperty.CreateValue(); 

     //and here you assign values without knowing their types, 
     //but they will still be typed 
     valueForDto.ValueInRoot = dto.ValueInRoot; 
    //} 
    //if ...(B.....Z) 
} 
+0

優秀,我看到這兩個大的區別是:1屬性創造價值。 2-由於所有的Value類都具有相同的Value屬性,因此將其設置爲根的抽象屬性。感謝您的時間,我學到了新的東西:D –

0

舉一個開始: 我要說的是一些可能的解決方案是迭代從RootValue延伸的所有類的構造函數,發現一些有XProperty說法,叫它,而且價值動態