我有一个这样的课
public class Child
{
public string ToXml()
{
return "Child : ToXml()";
}
public string ToXml( params string[] fields )
{
return "Child : ToXml(...)";
}
}
Run Code Online (Sandbox Code Playgroud)
创建类Child的实例并调用ToXml()返回第一个重载的函数,该函数很好并且花花公子.
var obj = new Child();
Console.WriteLine( obj.ToXml() );
Run Code Online (Sandbox Code Playgroud)
输出:
Child : ToXml()
Run Code Online (Sandbox Code Playgroud)
但是当我添加一个Parent类并将Child类更改为:
public class Parent
{
public virtual string ToXml()
{
return "Parent : ToXml()";
}
}
public class Child : Parent
{
public override string ToXml()
{
return "Child : ToXml()";
}
public string ToXml( params string[] fields )
{
return "Child : ToXml(...)";
}
}
Run Code Online (Sandbox Code Playgroud)
输出已更改为:
Child : ToXml(...)
Run Code Online (Sandbox Code Playgroud)
我的问题是,为什么这样的行为?(我使用的是使用.NET 3.5的VS2010)
我通过将第二个重载函数更改为"修复"此问题:(我取出了params关键字
public class Child : Parent
{
public override string ToXml()
{
return "Child : ToXml()";
}
public string ToXml( string[] fields )
{
return "Child : ToXml(...)";
}
}
Run Code Online (Sandbox Code Playgroud)
这让我想到了我的第二个问题(让我知道我是否应该把它分成两个不同的帖子),这些功能之间有什么区别
ToXml( params string[] fields )
Run Code Online (Sandbox Code Playgroud)
和
ToXml( string[] fields )
Run Code Online (Sandbox Code Playgroud)
当我调用这样的函数时,它们似乎都工作:
var obj = new Child();
Console.WriteLine( obj.ToXml( new [] { "foo", "bar" ) );
Run Code Online (Sandbox Code Playgroud)
为什么这样的行为?
目前尚不清楚"喜欢这个"是什么意思,所以首先,让我们正确地描述行为.您遇到的行为是:出于重载解析的目的,派生类型上的适用候选方法总是优于基类型上的适用候选方法.而且,虚方法被认为是声明它的类型的方法,而不是覆盖它的类型.
还不清楚"为什么"是什么意思?"为什么"这些问题很难回答; 在某种意义上,问题已经得到解答:为什么编译器会表现出这种行为?因为这是超载分辨率打破的指定规则的结果.但是你可能会说这个问题已被乞求; 现在的问题是"那么为什么规范是这样编写的呢?"
规范是这样编写的,因为这样做可以减轻脆弱的基类问题. 脆弱的基类问题是你有两个团队,一个在基类上工作,另一个在派生类上工作.如果在基类上工作的团队引入了一个新方法,那么这样做不应该改变使用派生类的代码的行为.如果是,则基类更改已"破坏"派生类行为.C#经过精心设计,可以缓解脆弱的基类问题.
即使将脆弱的基类问题排除在外,在派生类上优先考虑该方法也是有意义的.派生类的开发人员比基类的开发人员拥有更多信息.他们知道他们手里拿着香蕉; 基类的开发人员只知道他们有一个Fruit.调用应该转到开发人员编写的方法,他们尽可能提供更多信息.
然后你可能会说"好吧,这个问题再次被乞求;现在我想知道为什么减轻脆弱的基类问题很重要".而不是继续这种无限的倒退,我只会把它留在那; 如果你想了解更多,那就问一个不太模糊的问题.
如果脆弱基类故障缓解的主题让您感兴趣,请考虑阅读我冗长的系列文章.
这些功能有什么区别
不同之处在于,一个人可能是其扩展形式或正常形式的适用候选人,而另一个人只有一个适用的候选人形式.
| 归档时间: |
|
| 查看次数: |
261 次 |
| 最近记录: |