这是否违反了里氏替换原则,如果是这样,我该怎么办呢? [英] Does this violate the Liskov substitution principle, and if so, what do I do about it?

查看:132
本文介绍了这是否违反了里氏替换原则,如果是这样,我该怎么办呢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用情况:我使用的数据模板匹配查看到一个ViewModel。通过检查最派生类型的具体类型的数据模板提供的工作,他们不看什么接口提供,所以我必须这样做没有接口。

Use case: I'm using data templates to match a View to a ViewModel. Data templates work by inspecting the most derived type of the concrete type provided, and they don't look at what interfaces it provides, so I have to do this without interfaces.

我在这里简化的例子,离开了NotifyPropertyChanged等,但在现实世界中,视图是要绑定到Text属性。为简单起见,假设有一个TextBlock视图将绑定到ReadOnlyText和一个文本框会绑定到WritableText视图。

I'm simplifying the example here and leaving out NotifyPropertyChanged, etc., but in the real world, a View is going to bind to the Text property. For simplicity, imagine that a View with a TextBlock would bind to a ReadOnlyText and a View with a TextBox would bind to WritableText.

class ReadOnlyText
{
    private string text = string.Empty;

    public string Text
    {
        get { return text; }
        set
        {
            OnTextSet(value);
        }
    }

    protected virtual void OnTextSet(string value)
    {
        throw new InvalidOperationException("Text is readonly.");
    }

    protected void SetText(string value)
    {
        text = value;
        // in reality we'd NotifyPropertyChanged in here
    }
}

class WritableText : ReadOnlyText
{
    protected override void OnTextSet(string value)
    {
        // call out to business logic here, validation, etc.
        SetText(value);
    }
}



通过覆盖OnTextSet和改变其行为,我是不是违反 LSP ?如果是这样,有什么更好的方法来做到这一点?

By overriding OnTextSet and changing its behavior, am I violating the LSP? If so, what's a better way to do it?

推荐答案

LSP指出,一个子类应该substiutable为它的父类(见计算器这里问题)。要问自己的问题是,可写文本类型的只读的文字?答案显然是否,实际上这些是相互排斥的。所以,是的,这个代码违反LSP。然而,是可写的文本键入阅读文本(而不是只读文本)?答案是是。所以,我认为答案是看它是什么你想在每种情况下做的,并可能改变抽象一点如下:

LSP states that a subclass should be substiutable for it's superclass (see stackoverflow question here). The question to ask yourself is, "Is writeable text a type of readonly text?" The answer is clearly "no", in fact these are mutually exclusive. So, yes, this code violates LSP. However, is writable text a type of readable text (not readonly text)? The answer is "yes". So I think the answer is to look at what it is you're trying to do in each case and possibly to change the abstraction a bit as follows:

class ReadableText
{
    private string text = string.Empty;
    public ReadableText(string value)
    {
        text = value;
    }

    public string Text
    {
        get { return text; }
    }
}          

class WriteableText : ReadableText
{
    public WriteableText(string value):base(value)
    {

    }

    public new string Text
    {
        set
        {
            OnTextSet(value);
        }
        get
        {
            return base.Text;
        }
    }
    public void SetText(string value)
    {
        Text = value;
        // in reality we'd NotifyPropertyChanged in here       
    }
    public void OnTextSet(string value)
    {
        // call out to business logic here, validation, etc.       
        SetText(value);
    }
}     



只是要清楚,我们隐藏文本物业使用上的可写类的Text属性的新关键字可读类。结果
从的
http://msdn.microsoft.com/en-us/library/ms173152(VS.80)的.aspx
当新的关键字时,新的类成员被调用,而不是已被替换的基类成员。这些基类成员称为隐藏成员。如果派生类的实例强制转换为基类的一个实例隐藏类成员仍可以调用。

Just to be clear, we're hiding the Text property from the Readable class using the new keyword on the Text property in the Writeable class.
From http://msdn.microsoft.com/en-us/library/ms173152(VS.80).aspx: When the new keyword is used, the new class members are called instead of the base class members that have been replaced. Those base class members are called hidden members. Hidden class members can still be called if an instance of the derived class is cast to an instance of the base class.

这篇关于这是否违反了里氏替换原则,如果是这样,我该怎么办呢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆