有人能给我一个很好的理由,为什么在C#中,链式构造函数总是在任何构造函数体之前被调用?
.NET允许您在构造函数中的任何位置调用链式构造函数,那么为什么C#强制您在构造函数体执行之前执行它?
我曾写信给安德斯H并问过他,尽管他一定很忙,但他还是很乐意花时间回复。不幸的是,他设法回答了我实际上没有问过的问题(关于命名的构造函数。)
所以,出于好奇,我想我会在这里问,因为我个人认为这个限制没有一个合理的理由,所以希望我会受到重新教育: - )
只是澄清一下。 .NET CLR规则是必须调用1个构造函数,只有1个构造函数,并且只能调用一次。所以在CLR中这些是有效的
public class Meh
{
public Meh()
{
Console.WriteLine("Meh()");
this("Hello");
}
public Meh(string message)
{
Console.WriteLine("Meh {0}", message);
base();
}
}
但不是在C#
答案 0 :(得分:6)
使链式构造函数首先执行保证所有基类元素至少在派生类中可用,因为它们在基类中。允许链接的构造函数在任意点执行将是一种权衡,几乎没有明显的好处。
允许链式构造函数的任意入口点也会阻止延迟创建基类,因为这样的特性可能会运行链式构造函数两次。
答案 1 :(得分:1)
/ *因为您可以在delphi中执行以下注释代码 公共类BaseClass { public BaseClass(string sSql) { ExecSQL(sSql); //执行查询 } }
public class DerivedClass : BaseClass
{
public DerivedClass(int i, DateTime dt)
{
string sSql = "";
//construct sSql based on i, dt
base(sSql);
//do something else
}
}
* /
//按照以下代码处理基本construtor代码。 公共类BaseClass { public BaseClass() { //没做什么 }
public BaseClass(string sSql)
{
ExecSQL(sSql);
//DO NOT do anything else
}
public BaseClass(int i, DateTime dt)
{
//in base class ignore the parameters.
string sWhereClause = "";
string sSql = setSQL(sWhereClause);
ExecSQL(sWhereClause);
//DO NOT do anything else
}
protected virtual string setSQL(string value)
{
//set the sql
string sSql = "";
//add value into sSql
return sSql;
}
protected virtual void ExecSQL(string sSql)
{
int i = 1;
//execute query
}
}
public class DerivedClass: BaseClass
{
//public DerivedClass(string sSql):base (sSql){}
public DerivedClass()
{
//do nothing
}
public DerivedClass(string sSql)
{
ExecSQL(sSql);
//DO NOT do anything else
}
public DerivedClass(int i, DateTime dt)
{
ExecSQL(i, dt);
//do something else after base execution
}
protected void ExecSQL(int i, DateTime dt) //overloaded procedure
{
string sWhereClause = "";
//construct wherclause based on i, dt
string sSql = setSQL(sWhereClause); //calls baseclass function
base.ExecSQL(sWhereClause); //calls baseclass procedure
}
}
DerivedClass mdD = new DerivedClass(2,DateTime.Now); BaseClass mdB = new BaseClass(“sql”);
答案 2 :(得分:0)
既然你说“主观”,我想你不是在追求历史原因;这样:
答案 3 :(得分:0)
因此它与基本构造函数一致。当您使用:base()引用它们时,在构造函数之前调用基类构造函数,因此它有意义:this()具有相同的语义。
另外,没有一个明智的用例可以让它以相反的方式运作。
答案 4 :(得分:0)
如果有正确的理由不应该提供此功能,那么CLR或其他.NET语言将不支持它。我只能得出结论,答案是其中之一“因为它总是这样”,并且限制可能只是从C ++或其他东西复制。
答案 5 :(得分:0)
当您传递基础构造函数的参数需要验证检查时,这是一个问题。这不应该在基础构造函数中完成,也不能在派生类中完成。
(我在这里假设一个人不会有一个无参数的构造函数。我不能在我的情况下拥有它,因为它要求不应该有一个。)
我无法看到一个优雅的解决方案。