2013-12-17 89 views
1

編程類型的對象編程類型的對象

C#mvc4項目

我有兩個類似的ViewModels,包含了十幾個複雜的對象,我想打電話從我的創建和編輯操作的常用方法填充ViewModels。

東西沿着這

private void loadMdlDtl(CreateViewModel cvM, EditViewModel evM) 
{ 
    If (vM1 != null) { var vM = vM1} 
    If (vM2 != null) { var vM = vM2} 

    // about two dozen complex objects need to be populated 
    vM.property1 = …; 
    vM.property2 = …; 
    … 
} 

行這並不是因爲vM工作不在範圍內。

有什麼辦法以編程方式鍵入vM對象,以便我不必創建兩個loadModel方法或以其他方式重複大量代碼?

SOLUTION:

創建一個接口:

public class CreateViewModel : IViewModels, IValidatableObject 
{ 
    string property1 { get; set; } 
    int property2 { get; set; } 
    IEnumerable<ValidationResult> Validate(ValidationContext validationContext); 
    { 
    // implementation 
    } 
} 

public class EditViewModel : IViewModels, IValidatableObject 
{ 
    string property1 { get; set; } 
    int property2 { get; set; } 
    IEnumerable<ValidationResult> Validate(ValidationContext validationContext); 
    { 
    // implementation 
    } 
} 

呼叫從通過視圖模型操作方法:

public interface IViewModels 
{ 
    string property1 { get; set; } 
    int property2 { get; set; } 
    IEnumerable<ValidationResult> Validate(ValidationContext validationContext); 
} 

有無視圖模型從接口繼承

public ActionResult Create() 
{ 
    var vM = new CreateViewModel(); 
    ... 
    loadMdlDtl(vM); 
    ... 
} 

但現在接受的界面,而不是視圖模型進入方法:

private void loadMdlDtl(IViewModel vM) 
{ 
    // implementation 
} 
+0

我相信它應該是僞C#代碼。 –

回答

4

既然你要訪問的所有對象相同的屬性和/或方法,你可以定義這樣的屬性界面和方法。讓每個對象實現該接口。

public interface IMyCommonStuff 
{ 
    string property1 { get; set; } 
    int property2 { get; set; } 
    int SomeMethod(); 
} 

UPDATE

如果一些方法和/或屬性具有相同的實現方式中,該實現可在一個共同的基類型來完成。我建議在對對象進行操作時仍然使用接口定義。例如:

public class MyCommonImplementation : IMyCommonStuff 
{ 
    public virtual int SomeMethod() 
    { 
     // Implementation goes here. 
    } 

    public string property1 { get; set; } 

    public int property2 { get; set; } 
} 

public class MyConcreteSubclass : MyCommonImplementation, IMyCommonStuff 
{ 
    // Add only the things that make this concrete subclass special. Everything 
    // else is inherited from the base class 
} 
+0

也許你可以詳細闡述一下,但似乎會產生更多的代碼。那麼loadModelDtl方法是不是必須分別在每個對象中實現?創建不帶接口的第二個loadModelDtl方法不是更簡單嗎?我的目標是能夠重新使用代碼。 – Joe

+0

使用接口方法創建的唯一重要的額外代碼是接口定義本身。讓您的對象彼此相似以通過接口表達相似性的好處是非常重要的。接口使用導致代碼重用。 –

+0

我沒跟着。我如何重新使用'loadModelDtl's'代碼?有了接口,我將不得不實施兩次。如果可以,請提供代碼示例。 – Joe

1

Eric的回答是這樣做的標準方法,但如果你想節省時間,你可以使用dynamic關鍵字來定義vM,如:

dynamic vM; 
if (vM1 != null) vM = vM1; 
if (vM2 != null) vM = vM2; 

//about two dozen complex objects need to be populated 
vM.property1 = …; 
vM.property2 = …; 
… 
+1

請注意:如果你不小心,'動態'可以帶來相當的性能損失!見http://stackoverflow.com/questions/7478387/dynamic-and-performance – Xcelled194

+0

@Joe:沒有工作?什麼沒有用?錯誤是什麼?您在問題中發佈的代碼與此答案中的代碼完全兼容。 – dotNET

+0

@Joe:通過將聲明更改爲'dynamic vM = null',可以避免第一次警告。第二個讓我困惑。這兩個if語句之前或之後是「FirstOrDefault」行嗎? – dotNET