2013-12-17 2 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 или иным образом дублировать много кода?

РЕШЕНИЕ:

Создание интерфейса:

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

имеет вид модель унаследует от интерфейса:

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

ОБНОВЛЕНИЕ

Если некоторые из методов и/или свойств имеют одинаковые реализации, что реализация может быть сделана в общем базовый типе. Я бы предложил использовать определение интерфейса, действуя на ваши объекты. Пример:

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? С интерфейсом я должен был бы реализовать его дважды. Если возможно, вы можете предоставить образец кода. – Joe

1

Ответ Эрика это стандартный способ сделать это, но если вы хотите сэкономить время, вы можете использовать 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

Просто примечание: 'dynamic' может нести штраф за производительность, если вы не будете осторожны! См. Http://stackoverflow.com/questions/7478387/dynamic-and-performance – Xcelled194

+0

@Joe: Не работает? Что не сработало? Какая ошибка? Код, который вы опубликовали в вопросе, полностью совместим с тем, который указан в этом ответе. – dotNET

+0

@Joe: Первое предупреждение можно избежать, изменив объявление на 'dynamic vM = null'. Второй меня смущает. Это строка 'FirstOrDefault' до или после двух операторов' if'? – dotNET

Смежные вопросы