Edw*_*vey 11 c# methods constructor overriding
这是一个过于简单的例子,但我有一些现实生活中的代码在概念上做同样的事情(试图验证派生类的"set"访问器方法的值),并且Analyzer给了我"不要在构造函数中调用可覆盖的方法".我试图找出是否应该更改我的代码,或忽略警告.我想不出任何理由我应该注意这个警告.
public abstract class SimpleUrl
{
protected string _url;
public abstract string Url { get; set; }
public SimpleUrl()
{ }
public SimpleUrl(string Url)
{
this.Url = Url;
}
}
public class HttpUrl : SimpleUrl
{
public HttpUrl()
{ }
public HttpUrl(string Url)
{
this.Url = Url;
}
public override string Url
{
get
{
return this._url;
}
set
{
if (value.StartsWith("http://"))
this._url = value;
else
throw new ArgumentException();
}
}
}
Run Code Online (Sandbox Code Playgroud)
正如TS所说(谢谢TS),在实例化派生类型时,将始终调用基础构造函数.如果你像我在问题中所做的那样,衍生构造函数没有明确指定要使用哪个基础构造函数,那么使用无参数基础构造函数.
public HttpUrl() // : base() is implied.
Run Code Online (Sandbox Code Playgroud)
和
public HttpUrl(string Url) // : base() is still implied.
// Parameterless. Not :base(Url)
Run Code Online (Sandbox Code Playgroud)
所以这个问题的完整答案是:如果你密封了派生类,那么在基类中声明的抽象或虚方法只能在基类中覆盖.因此,要创建干净的代码,不要在基础构造函数中运行此行:
this.Url = Url; // Don't do this in the base constructor
Run Code Online (Sandbox Code Playgroud)
相反,你应该"密封"衍生类(或方法).如下:
public abstract class SimpleUrl
{
protected string _url;
public abstract string Url { get; set; }
// Optionally declare base constructors that do *not* call Url.set
// Not sure why these constructors are optional in the base, but
// required in the derivative classes. But they are.
public SimpleUrl()
{ }
}
public sealed class HttpUrl : SimpleUrl
{
public HttpUrl() // Not sure why this is required, but it is.
{ }
public HttpUrl(string Url)
{
// Since HttpUrl is sealed, the Url set accessor is no longer
// overridable, which makes the following line safe.
this.Url = Url;
}
public override string Url
{
get
{
return this._url;
}
set
{
if (value.StartsWith("http://"))
this._url = value;
else
throw new ArgumentException();
}
}
}
Run Code Online (Sandbox Code Playgroud)
或者,如果您只是密封可覆盖的方法(使其不再被任何其他衍生类别覆盖),则不需要密封整个衍生类别.
public class HttpUrl : SimpleUrl
{
// ...
public override sealed string Url
// ...
Run Code Online (Sandbox Code Playgroud)