Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>If BusinessObject and Person classes (and their VM counterparts) are abstract, then you could access the right Model like this:</p> <pre><code>public abstract class BusinessObjectViewModel : ViewModelBase { protected abstract BusinessObject BusinessObject { get; } protected BusinessObject Model { get { return this.BusinessObject; } } } public abstract class PersonViewModel : BusinessObjectViewModel { protected abstract Person Person { get; } protected new Person Model { get { return this.Person; } } protected override sealed BusinessObject BusinessObject { get { return this.Model; } } } public class CustomerViewModel : PersonViewModel { protected new Customer Model { get; set; } protected override sealed Person Person { get { return this.Model; } } } public class EmployeeViewModel : PersonViewModel { protected new Employee Model { get; set; } protected override sealed Person Person { get { return this.Model; } } } </code></pre> <p>This way every derived VM class provides a value for its base VM Model property by implementing abstract property and hides a base class Model property, so every VM works with Model property of an appropriate type (so no casting is required).</p> <p>This approach has its benefits and drawbacks:</p> <p>Benefits:</p> <ul> <li>No casting involved.</li> </ul> <p>Drawbacks:</p> <ul> <li>Works only if base classes (BusinessObjectViewModel and PersonViewModel) are abstract because there must exist an abstract property that is implemented by the derived class and provides a Model instance to these base classes.</li> <li>Model property should not be accessed in the base class constructors, because constructor chaining goes from base class to the most derived class. The most derived class constructor will set Model, so base class constructors are called to early to see it. This can be avoided by passing Model as a parameter through constructors.</li> <li>BusinessObject and Person properties are unnecessary seen by the derived classes. EditorBrowsableAttribute might help here for Intellisense, but only when code is used by another assembly in different Visual Studio solution (this is Visual Studio specific behavior).</li> <li>Performance. When base classes access Model, code will go through a chain of virtual properties. But since since implemented abstract properties are marked as sealed, virtual table lookup should not be so much performance degrading.</li> <li>Doesn't scale nicely. For deep class hierarchies code would contain many unnecessary members.</li> </ul> <p>Another approach would be:</p> <pre><code>public class BusinessObjectViewModel : ViewModelBase { protected BusinessObject Model { get; private set; } public BusinessObjectViewModel(BusinessObject model) { this.Model = model; } } public class PersonViewModel : BusinessObjectViewModel { protected new Person Model { get { return (Person)base.Model; } } public PersonViewModel(Person model) : base(model) { } } public class CustomerViewModel : PersonViewModel { protected new Customer Model { get { return (Customer)base.Model; } } public CustomerViewModel(Customer model) : base(model) { } } public class EmployeeViewModel : PersonViewModel { protected new Employee Model { get { return (Employee)base.Model; } } public EmployeeViewModel(Employee model) : base(model) { } } </code></pre> <p>Benefits:</p> <ul> <li>Base classes do not need to be abstract.</li> <li>Model can be accessed through base class constructors.</li> <li>No unnecessary additional properties.</li> </ul> <p>Drawbacks:</p> <ul> <li>Casting.</li> </ul> <p>Based on this analysis, I would go with a second option because fixing its only drawback, casting performance, would be unnecessary micro-optimization that would not be noticeable in WPF context.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload