Jon Skeet在他的视频中提到了这个问题
(虽然没有提供答案).
(虽然没有提供答案).
假设我们有一个名为Person的类
Person类具有Name属性
然后我们有另一个班,间谍.
当然,间谍是一个人,所以我们将从Person类派生.
public class Person { public string Name { get; set; } } public class Spy : Person { }
我们不希望人们知道Spy的名字,所以我们希望这会给出一个编译错误:
static void ReportSpy(Spy spy) { string name = spy.Name; }
或者:
static void ReportSpy(Spy spy) { Person spyAsPerson = spy; string name = spyAsPerson.Name; }
我们怎么能防止这种事情发生呢?
解决方法
在基本Person类中使Name属性为virtual.在派生的Spy类中,覆盖该属性并在getter中抛出Exception.
public class Person { public virtual string Name { get; set; } } public class Spy : Person { public override string Name { get { throw new Exception("You never ask for a spy's name!"); } set { base.Name = value; } } }
但是,我建议不要抛出异常
get { return "**********"; }
因为,它打破了LSP(在另一个答案中提到).这意味着什么(只是一个例子),我总是可以这样做
Person x = new Spy();
并将其传递给其他方法,可能就像
void RegisterForNextBallGame(Person p) { playerList.Add(p.Name); }
这种方法不知道体育场周围的一些间谍漫游,在做一个简单的诚实任务时崩溃!
编辑
为了说清楚,这个名字= **********仍然不是一个正确的解决方案.它只会从异常中拯救!之后,人们可能会发现许多人在名称为**********的代码中走下来,这将导致后来的惊喜和其他问题.
更好的解决方案是更好的设计.检查内森的答案以获得一些暗示.