2

让我们考虑一个用于订单历史的域抽象类和考虑付款、取​​消、重新激活等事件的具体类(以下代码是一个非常简化的版本)

public abstract class OrderEvent
{
    protected OrderEvent(DateTime eventDate)
    {
        EventDate = eventDate;
    }

    public abstract string Description { get; }
    public DateTime EventDate { get; protected set; }
}

public class CancellationEvent : OrderEvent
{
    public CancellationEvent(DateTime cancelDate)
        : base(cancelDate)
    {

    }
    public override string Description { get { return "Cancellation"; } }
}

public class PaymentEvent : OrderEvent 
{
    public PaymentEvent(DateTime eventDate, decimal amount, PaymentOption paymentOption) : base(eventDate)
    {
        Description = description;
        Amount = amount;
        PaymentOption = paymentOption;
    }

    public override string Description { get{ return "Payment"; } }
    public decimal Amount { get; protected set; }
    public PaymentOption PaymentOption { get; protected set; }
}

现在我必须在这个域模型上为我的 ASP.NET MVC 项目构建一个 ViewModel,它将所有事件封装到一个类中,以便在视图上进行网格展示。

public class OrderHistoryViewModel
{
    public OrderHistoryViewModel(OrderEvent orderEvent)
    {
        // Here's my doubt

    }

    public string Date { get; protected set; }
    public string Description { get; protected set; }
    public string Amount { get; protected set; }
}

如何从具体类访问特定属性,例如 PaymentEvent 上的 Amount 属性,而不做一些像 switch 或 if 这样的臭事情?

谢谢!

4

1 回答 1

2

如果您使用 .NET 4 及更高版本,则正在进行双重调度:

public class OrderHistoryViewModel
{
    public OrderHistoryViewModel(OrderEvent orderEvent)
    {
       // this will resolve to appropriate method dynamically
       (this as dynamic).PopulateFrom((dynamic)orderEvent);
    }

    void PopulateFrom(CancellationEvent e)
    {
    }

    void PopulateFrom(PaymentEvent e)
    {
    }

    public string Date { get; protected set; }
    public string Description { get; protected set; }
    public string Amount { get; protected set; }
}

Personally, I don't really mind doing if/switch statements in this type of code. This is application boundary code that doesn't need to be very pretty and having it be explicit can be helpful. What C# really needs are algebraic types such as the union type in F#. This way, the compiler will ensure that you handle all cases (sub-types) explicitly.

于 2012-12-07T19:11:31.590 回答